* [Qemu-devel] [PATCH v3 00/50] Hi,
@ 2017-09-11 11:05 Marc-André Lureau
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 01/50] qlit: add qobject_from_qlit() Marc-André Lureau
` (51 more replies)
0 siblings, 52 replies; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:05 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau
In order to clean-up some hacks in qapi (having to unregister commands
at runtime), I proposed a "[PATCH v5 02/20] qapi.py: add a simple #ifdef condition"
(see http://lists.gnu.org/archive/html/qemu-devel/2016-08/msg03106.html).
However, we decided to drop that patch from the series and solve the
problem later. The main issues were:
- the syntax was awkward to the JSON schema and documentation
- the evaluation of the condition was done in the qapi scripts, with
very limited capability
- each target/config would need different generated files.
Instead, it could defer the #if evaluation to the C-preprocessor.
With this series, top-level qapi JSON entity can take 'if' keys:
{ 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
'if': 'defined(TEST_IF_STRUCT)' }
Members can be exploded as dictionnary with 'type'/'if' keys:
{ 'struct': 'TestIfStruct', 'data':
{ 'foo': 'int',
'bar': { 'type': 'int', 'if': 'defined(TEST_IF_STRUCT_BAR)'} } }
Enum values can be exploded as dictionnary with 'type'/'if' keys:
{ 'enum': 'TestIfEnum', 'data':
[ 'foo',
{ 'name' : 'bar', 'if': 'defined(TEST_IF_ENUM_BAR)' } ] }
A good benefit from having conditional schema is that introspection
will reflect more accurately the capability of the server. Another
benefit is that it may help to remove some dead code when disabling a
functionality.
Starting from patch "qapi: add conditions to VNC type/commands/events
on the schema", the series demonstrate adding conditions, in order to
remove qmp_unregister_commands_hack(). The main difference with v2, is
the addition of a per-target schema in "build-sys: add a target
schema". This removes the NEED_CPU_H hack, and keep most of the qapi
files in common build.
There are a lot more things we could make conditional in the QAPI
schema, like pci/kvm/xen/numa/vde/slirp/posix/win32/vsock/lzo etc etc,
however I am still evaluating the implication of such changes both
externally and internally, for those interested, I can share my wip
branch.
Comments welcome,
v3:
- rebased (qlit is now merged upstream)
- solve the per-target #ifdef problem by using a target.json
and new qapi generated target files
- update some commit messages based on Markus review
- more schema error reporting
- move the ifcond argument closer to info/doc
- use mcgen() in gen_if()/gen_endif()
- simplify "modify to_qlit() to take an optional suffix"
- fix generated qlit indentation
- fix temporary build break by merging #if types & visitors patch
- fix some redundant condtionals generation
- change enum visitor to take QAPISchemaMember
- reject unknown dictionnary keys in { .., 'if': ..}
- split qapi test visitor print() with trailing ',' trick
Marc-André Lureau (50):
qlit: add qobject_from_qlit()
qapi: generate a literal qobject for introspection
qapi2texi: minor python code simplification
qapi: add 'if' to top-level expressions
qapi: add tests for invalid 'if'
qapi: pass 'if' condition into QAPISchemaEntity objects
qapi: add 'ifcond' to visitor methods
qapi: mcgen() shouldn't indent # lines
qapi: add #if/#endif helpers
qapi-introspect: modify to_qlit() to append ',' on level > 0
qapi-introspect: modify to_qlit() to generate #if code
qapi-introspect: add preprocessor conditions to generated QLit
qapi-commands: add #if conditions to commands
qapi-event: add #if conditions to events
qapi-types: refactor variants handling
qapi-types: add #if conditions to types & visitors
qapi: do not define enumeration value explicitely
qapi: change enum visitor to take QAPISchemaMember
qapi: add 'if' to enum members
qapi-event: add 'if' condition to generated enum
qapi: add #if conditions on generated enum members
tests: add some enum members tests
qapi: add 'if' to struct members and implicit objects members
qapi: add some struct member tests
qapi: add #if conditions to generated struct members
qapi: add 'if' on union variants
qapi: add #if conditions to generated variants
qapi: add 'if' to alternate variant
qapi: add tests for invalid alternate
qapi: add #if conditions to generated alternate variants
docs: document schema configuration
qapi2texi: add 'If:' section to generated documentation
qapi2texi: add 'If:' condition to enum values
qapi2texi: add 'If:' condition to struct members
qapi2texi: add condition to variants
qapi: add conditions to VNC type/commands/events on the schema
qapi: add conditions to SPICE type/commands/events on the schema
qapi: add conditions to REPLICATION type/commands on the schema
qapi-commands: don't initialize command list in qmp_init_marshall()
qapi: add -i/--include filename.h
qapi: add a 'unit' pragma
qapi: add a -u/--unit option to specify which unit to visit
build-sys: move qmp-introspect per target
build-sys: add a target schema
qapi: make rtc-reset-reinjection depend on TARGET_I386
qapi: make s390 commands depend on TARGET_S390X
target.json: add a note about query-cpu* not being s390x-specific
qapi: make query-gic-capabilities depend on TARGET_ARM
qapi: make query-cpu-model-expansion depend on s390 or x86
qapi: make query-cpu-definitions depend on specific targets
qapi-schema.json | 212 +-----------
qapi/block-core.json | 15 +-
qapi/char.json | 10 +-
qapi/crypto.json | 3 +-
qapi/migration.json | 12 +-
qapi/target.json | 228 +++++++++++++
qapi/ui.json | 75 +++--
scripts/qapi.py | 372 +++++++++++++++------
scripts/qapi-commands.py | 13 +-
scripts/qapi-event.py | 12 +-
scripts/qapi-introspect.py | 121 ++++---
scripts/qapi-types.py | 71 ++--
scripts/qapi-visit.py | 24 +-
scripts/qapi2texi.py | 52 +--
include/qapi/qmp/qlit.h | 2 +
include/sysemu/arch_init.h | 11 -
ui/vnc.h | 2 +
crypto/cipher-builtin.c | 9 +
crypto/cipher-gcrypt.c | 10 +-
crypto/cipher-nettle.c | 14 +-
crypto/cipher.c | 13 +-
hmp.c | 9 +-
hw/s390x/s390-skeys.c | 2 +-
hw/timer/mc146818rtc.c | 2 +-
migration/colo.c | 16 +-
monitor.c | 73 +---
qga/main.c | 1 +
qmp.c | 72 +---
qobject/qlit.c | 36 ++
stubs/arch-query-cpu-def.c | 10 -
stubs/arch-query-cpu-model-baseline.c | 12 -
stubs/arch-query-cpu-model-comparison.c | 12 -
stubs/arch-query-cpu-model-expansion.c | 12 -
target/arm/helper.c | 3 +-
target/arm/monitor.c | 2 +-
target/i386/cpu.c | 5 +-
target/ppc/translate_init.c | 3 +-
target/s390x/cpu_models.c | 9 +-
tests/check-qlit.c | 26 ++
tests/test-crypto-cipher.c | 2 +
tests/test-qmp-commands.c | 7 +
tests/test-qobject-input-visitor.c | 10 +-
Makefile | 29 +-
Makefile.objs | 3 +-
Makefile.target | 4 +
docs/devel/qapi-code-gen.txt | 69 +++-
hmp-commands-info.hx | 2 +
stubs/Makefile.objs | 4 -
tests/Makefile.include | 10 +-
tests/qapi-schema/alternate-dict-invalid.err | 1 +
...ict-member.exit => alternate-dict-invalid.exit} | 0
tests/qapi-schema/alternate-dict-invalid.json | 4 +
...-dict-member.out => alternate-dict-invalid.out} | 0
tests/qapi-schema/bad-if-empty-list.err | 1 +
tests/qapi-schema/bad-if-empty-list.exit | 1 +
tests/qapi-schema/bad-if-empty-list.json | 3 +
tests/qapi-schema/bad-if-empty-list.out | 0
tests/qapi-schema/bad-if-empty.err | 1 +
tests/qapi-schema/bad-if-empty.exit | 1 +
tests/qapi-schema/bad-if-empty.json | 3 +
tests/qapi-schema/bad-if-empty.out | 0
tests/qapi-schema/bad-if.err | 1 +
tests/qapi-schema/bad-if.exit | 1 +
tests/qapi-schema/bad-if.json | 3 +
tests/qapi-schema/bad-if.out | 0
tests/qapi-schema/comments.out | 14 +-
tests/qapi-schema/doc-good.out | 17 +-
tests/qapi-schema/empty.out | 9 +-
tests/qapi-schema/enum-dict-member-invalid.err | 1 +
tests/qapi-schema/enum-dict-member-invalid.exit | 1 +
tests/qapi-schema/enum-dict-member-invalid.json | 2 +
tests/qapi-schema/enum-dict-member-invalid.out | 0
tests/qapi-schema/enum-dict-member-invalid2.err | 1 +
tests/qapi-schema/enum-dict-member-invalid2.exit | 1 +
tests/qapi-schema/enum-dict-member-invalid2.json | 2 +
tests/qapi-schema/enum-dict-member-invalid2.out | 0
tests/qapi-schema/enum-dict-member.err | 1 -
tests/qapi-schema/enum-dict-member.json | 2 -
tests/qapi-schema/enum-if-invalid.err | 1 +
tests/qapi-schema/enum-if-invalid.exit | 1 +
tests/qapi-schema/enum-if-invalid.json | 3 +
tests/qapi-schema/enum-if-invalid.out | 0
tests/qapi-schema/event-case.out | 9 +-
tests/qapi-schema/ident-with-escape.out | 9 +-
tests/qapi-schema/include-relpath.out | 14 +-
tests/qapi-schema/include-repetition.out | 14 +-
tests/qapi-schema/include-simple.out | 14 +-
tests/qapi-schema/indented-expr.out | 9 +-
tests/qapi-schema/qapi-schema-test.json | 36 ++
tests/qapi-schema/qapi-schema-test.out | 93 +++++-
tests/qapi-schema/struct-if-invalid.err | 1 +
tests/qapi-schema/struct-if-invalid.exit | 1 +
tests/qapi-schema/struct-if-invalid.json | 3 +
tests/qapi-schema/struct-if-invalid.out | 0
tests/qapi-schema/struct-member-type.err | 0
tests/qapi-schema/struct-member-type.exit | 1 +
tests/qapi-schema/struct-member-type.json | 2 +
tests/qapi-schema/struct-member-type.out | 12 +
tests/qapi-schema/test-qapi.py | 43 ++-
99 files changed, 1328 insertions(+), 735 deletions(-)
create mode 100644 qapi/target.json
delete mode 100644 stubs/arch-query-cpu-def.c
delete mode 100644 stubs/arch-query-cpu-model-baseline.c
delete mode 100644 stubs/arch-query-cpu-model-comparison.c
delete mode 100644 stubs/arch-query-cpu-model-expansion.c
create mode 100644 tests/qapi-schema/alternate-dict-invalid.err
rename tests/qapi-schema/{enum-dict-member.exit => alternate-dict-invalid.exit} (100%)
create mode 100644 tests/qapi-schema/alternate-dict-invalid.json
rename tests/qapi-schema/{enum-dict-member.out => alternate-dict-invalid.out} (100%)
create mode 100644 tests/qapi-schema/bad-if-empty-list.err
create mode 100644 tests/qapi-schema/bad-if-empty-list.exit
create mode 100644 tests/qapi-schema/bad-if-empty-list.json
create mode 100644 tests/qapi-schema/bad-if-empty-list.out
create mode 100644 tests/qapi-schema/bad-if-empty.err
create mode 100644 tests/qapi-schema/bad-if-empty.exit
create mode 100644 tests/qapi-schema/bad-if-empty.json
create mode 100644 tests/qapi-schema/bad-if-empty.out
create mode 100644 tests/qapi-schema/bad-if.err
create mode 100644 tests/qapi-schema/bad-if.exit
create mode 100644 tests/qapi-schema/bad-if.json
create mode 100644 tests/qapi-schema/bad-if.out
create mode 100644 tests/qapi-schema/enum-dict-member-invalid.err
create mode 100644 tests/qapi-schema/enum-dict-member-invalid.exit
create mode 100644 tests/qapi-schema/enum-dict-member-invalid.json
create mode 100644 tests/qapi-schema/enum-dict-member-invalid.out
create mode 100644 tests/qapi-schema/enum-dict-member-invalid2.err
create mode 100644 tests/qapi-schema/enum-dict-member-invalid2.exit
create mode 100644 tests/qapi-schema/enum-dict-member-invalid2.json
create mode 100644 tests/qapi-schema/enum-dict-member-invalid2.out
delete mode 100644 tests/qapi-schema/enum-dict-member.err
delete mode 100644 tests/qapi-schema/enum-dict-member.json
create mode 100644 tests/qapi-schema/enum-if-invalid.err
create mode 100644 tests/qapi-schema/enum-if-invalid.exit
create mode 100644 tests/qapi-schema/enum-if-invalid.json
create mode 100644 tests/qapi-schema/enum-if-invalid.out
create mode 100644 tests/qapi-schema/struct-if-invalid.err
create mode 100644 tests/qapi-schema/struct-if-invalid.exit
create mode 100644 tests/qapi-schema/struct-if-invalid.json
create mode 100644 tests/qapi-schema/struct-if-invalid.out
create mode 100644 tests/qapi-schema/struct-member-type.err
create mode 100644 tests/qapi-schema/struct-member-type.exit
create mode 100644 tests/qapi-schema/struct-member-type.json
create mode 100644 tests/qapi-schema/struct-member-type.out
--
2.14.1.146.gd35faa819
^ permalink raw reply [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 01/50] qlit: add qobject_from_qlit()
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
@ 2017-09-11 11:05 ` Marc-André Lureau
2017-09-13 13:51 ` Eric Blake
2017-12-06 14:37 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 02/50] qapi: generate a literal qobject for introspection Marc-André Lureau
` (50 subsequent siblings)
51 siblings, 2 replies; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:05 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau
Instanciate a QObject* form a literal QLitObject.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
include/qapi/qmp/qlit.h | 2 ++
qobject/qlit.c | 36 ++++++++++++++++++++++++++++++++++++
tests/check-qlit.c | 26 ++++++++++++++++++++++++++
3 files changed, 64 insertions(+)
diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h
index b18406bce9..56feb25e04 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 3c4882c784..df2ad97d33 100644
--- a/qobject/qlit.c
+++ b/qobject/qlit.c
@@ -82,3 +82,39 @@ bool qlit_equal_qobject(const QLitObject *lhs, const QObject *rhs)
return false;
}
+
+QObject *qobject_from_qlit(const QLitObject *qlit)
+{
+ 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();
+ QLitDictEntry *e;
+
+ for (e = qlit->value.qdict; e->key; e++) {
+ qdict_put_obj(qdict, e->key, qobject_from_qlit(&e->value));
+ }
+ return QOBJECT(qdict);
+ }
+ case QTYPE_QLIST: {
+ QList *qlist = qlist_new();
+ QLitObject *e;
+
+ for (e = qlit->value.qlist; e->type != QTYPE_NONE; e++) {
+ qlist_append_obj(qlist, qobject_from_qlit(e));
+ }
+ 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 c59ec1ab88..acd6e02e96 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] 118+ messages in thread
* [Qemu-devel] [PATCH v3 02/50] qapi: generate a literal qobject for introspection
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 01/50] qlit: add qobject_from_qlit() Marc-André Lureau
@ 2017-09-11 11:05 ` Marc-André Lureau
2017-12-06 15:17 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 03/50] qapi2texi: minor python code simplification Marc-André Lureau
` (49 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:05 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>
---
scripts/qapi-introspect.py | 83 ++++++++++++++++++++++----------------
monitor.c | 2 +-
tests/test-qobject-input-visitor.c | 11 +++--
docs/devel/qapi-code-gen.txt | 29 ++++++++-----
4 files changed, 76 insertions(+), 49 deletions(-)
diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
index 032bcea491..0002bc1a68 100644
--- a/scripts/qapi-introspect.py
+++ b/scripts/qapi-introspect.py
@@ -12,26 +12,36 @@
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, True)))
+ 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
@@ -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 9239f7adde..5685697f59 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 fe591814e4..7c1d10e274 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 f04c63fe82..0a90f2278a 100644
--- a/docs/devel/qapi-code-gen.txt
+++ b/docs/devel/qapi-code-gen.txt
@@ -1327,18 +1327,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] 118+ messages in thread
* [Qemu-devel] [PATCH v3 03/50] qapi2texi: minor python code simplification
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 01/50] qlit: add qobject_from_qlit() Marc-André Lureau
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 02/50] qapi: generate a literal qobject for introspection Marc-André Lureau
@ 2017-09-11 11:05 ` Marc-André Lureau
2017-12-06 15:19 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 04/50] qapi: add 'if' to top-level expressions Marc-André Lureau
` (48 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:05 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi2texi.py | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py
index a317526e51..73cfb01727 100755
--- a/scripts/qapi2texi.py
+++ b/scripts/qapi2texi.py
@@ -136,10 +136,9 @@ def texi_enum_value(value):
def texi_member(member, suffix=''):
"""Format a table of members item for an object type member"""
typ = member.type.doc_type()
- return '@item @code{%s%s%s}%s%s\n' % (
- member.name,
- ': ' if typ else '',
- typ if typ else '',
+ membertype = ': ' + typ if typ else ''
+ return '@item @code{%s%s}%s%s\n' % (
+ member.name, membertype,
' (optional)' if member.optional else '',
suffix)
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 04/50] qapi: add 'if' to top-level expressions
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (2 preceding siblings ...)
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 03/50] qapi2texi: minor python code simplification Marc-André Lureau
@ 2017-09-11 11:05 ` Marc-André Lureau
2017-12-06 15:46 ` Markus Armbruster
2017-12-06 16:23 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 05/50] qapi: add tests for invalid 'if' Marc-André Lureau
` (47 subsequent siblings)
51 siblings, 2 replies; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:05 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
Accept 'if' key in top-level elements, accepted as string or list of
string type. The following patches will modify the test visitor to
check the value is correctly saved, and generate #if/#endif code (as a
single #if/endif line or a series for a list).
Example of 'if' key:
{ 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
'if': 'defined(TEST_IF_STRUCT)' }
The generated code is for now *unconditional*. Later patches generate
the conditionals.
A following patch for qapi-code-gen.txt will provide more complete
documentation for 'if' usage.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi.py | 35 +++++++++++++++++++++++++++------
tests/test-qmp-commands.c | 6 ++++++
tests/qapi-schema/qapi-schema-test.json | 20 +++++++++++++++++++
tests/qapi-schema/qapi-schema-test.out | 22 +++++++++++++++++++++
4 files changed, 77 insertions(+), 6 deletions(-)
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 62dc52ed6e..20c1abf915 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -639,6 +639,26 @@ def add_name(name, info, meta, implicit=False):
all_names[name] = meta
+def check_if(expr, info):
+
+ def check_if_str(ifcond, info):
+ if ifcond == '':
+ raise QAPISemError(info, "'if' condition '' makes no sense")
+
+ ifcond = expr['if']
+ if isinstance(ifcond, str):
+ check_if_str(ifcond, info)
+ elif (isinstance(ifcond, list)
+ and all(isinstance(elt, str) for elt in ifcond)):
+ if ifcond == []:
+ raise QAPISemError(info, "'if' condition [] is useless")
+ for elt in ifcond:
+ check_if_str(elt, info)
+ else:
+ raise QAPISemError(
+ info, "'if' condition must be a string or a list of strings")
+
+
def check_type(info, source, value, allow_array=False,
allow_dict=False, allow_optional=False,
allow_metas=[]):
@@ -878,6 +898,8 @@ def check_keys(expr_elem, meta, required, optional=[]):
raise QAPISemError(info,
"'%s' of %s '%s' should only use true value"
% (key, meta, name))
+ if key == 'if':
+ check_if(expr, info)
for key in required:
if key not in expr:
raise QAPISemError(info, "Key '%s' is missing from %s '%s'"
@@ -903,27 +925,28 @@ def check_exprs(exprs):
if 'enum' in expr:
meta = 'enum'
- check_keys(expr_elem, 'enum', ['data'], ['prefix'])
+ check_keys(expr_elem, 'enum', ['data'], ['if', 'prefix'])
enum_types[expr[meta]] = expr
elif 'union' in expr:
meta = 'union'
check_keys(expr_elem, 'union', ['data'],
- ['base', 'discriminator'])
+ ['base', 'discriminator', 'if'])
union_types[expr[meta]] = expr
elif 'alternate' in expr:
meta = 'alternate'
- check_keys(expr_elem, 'alternate', ['data'])
+ check_keys(expr_elem, 'alternate', ['data'], ['if'])
elif 'struct' in expr:
meta = 'struct'
- check_keys(expr_elem, 'struct', ['data'], ['base'])
+ check_keys(expr_elem, 'struct', ['data'], ['base', 'if'])
struct_types[expr[meta]] = expr
elif 'command' in expr:
meta = 'command'
check_keys(expr_elem, 'command', [],
- ['data', 'returns', 'gen', 'success-response', 'boxed'])
+ ['data', 'returns', 'gen', 'success-response', 'boxed',
+ 'if'])
elif 'event' in expr:
meta = 'event'
- check_keys(expr_elem, 'event', [], ['data', 'boxed'])
+ check_keys(expr_elem, 'event', [], ['data', 'boxed', 'if'])
else:
raise QAPISemError(expr_elem['info'],
"Expression is missing metatype")
diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c
index 904c89d4d4..9b9a7ffee7 100644
--- a/tests/test-qmp-commands.c
+++ b/tests/test-qmp-commands.c
@@ -10,6 +10,12 @@
static QmpCommandList qmp_commands;
+/* #if defined(TEST_IF_CMD) */
+void qmp_TestIfCmd(TestIfStruct *foo, Error **errp)
+{
+}
+/* #endif */
+
void qmp_user_def_cmd(Error **errp)
{
}
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index c72dbd8050..dc2c444fc1 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -188,3 +188,23 @@
'data': { 'a': ['__org.qemu_x-Enum'], 'b': ['__org.qemu_x-Struct'],
'c': '__org.qemu_x-Union2', 'd': '__org.qemu_x-Alt' },
'returns': '__org.qemu_x-Union1' }
+
+# test 'if' condition handling
+
+{ 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
+ 'if': 'defined(TEST_IF_STRUCT)' }
+
+{ 'enum': 'TestIfEnum', 'data': [ 'foo', 'bar' ],
+ 'if': 'defined(TEST_IF_ENUM)' }
+
+{ 'union': 'TestIfUnion', 'data': { 'foo': 'TestStruct' },
+ 'if': 'defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)' }
+
+{ 'alternate': 'TestIfAlternate', 'data': { 'foo': 'int', 'bar': 'TestStruct' },
+ 'if': 'defined(TEST_IF_ALT) && defined(TEST_IF_STRUCT)' }
+
+{ 'command': 'TestIfCmd', 'data': { 'foo': 'TestIfStruct' },
+ 'if': 'defined(TEST_IF_CMD) && defined(TEST_IF_STRUCT)' }
+
+{ 'event': 'TestIfEvent', 'data': { 'foo': 'TestIfStruct' },
+ 'if': 'defined(TEST_IF_EVT) && defined(TEST_IF_STRUCT)' }
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index 3b1e9082d3..7fbaea19bc 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -52,6 +52,22 @@ enum QEnumTwo ['value1', 'value2']
prefix QENUM_TWO
enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
prefix QTYPE
+alternate TestIfAlternate
+ tag type
+ case foo: int
+ case bar: TestStruct
+command TestIfCmd q_obj_TestIfCmd-arg -> None
+ gen=True success_response=True boxed=False
+enum TestIfEnum ['foo', 'bar']
+event TestIfEvent q_obj_TestIfEvent-arg
+ boxed=False
+object TestIfStruct
+ member foo: int optional=False
+object TestIfUnion
+ member type: TestIfUnionKind optional=False
+ tag type
+ case foo: q_obj_TestStruct-wrapper
+enum TestIfUnionKind ['foo']
object TestStruct
member integer: int optional=False
member boolean: bool optional=False
@@ -172,6 +188,12 @@ object q_obj_EVENT_D-arg
member b: str optional=False
member c: str optional=True
member enum3: EnumOne optional=True
+object q_obj_TestIfCmd-arg
+ member foo: TestIfStruct optional=False
+object q_obj_TestIfEvent-arg
+ member foo: TestIfStruct optional=False
+object q_obj_TestStruct-wrapper
+ member data: TestStruct optional=False
object q_obj_UserDefFlatUnion2-base
member integer: int optional=True
member string: str optional=False
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 05/50] qapi: add tests for invalid 'if'
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (3 preceding siblings ...)
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 04/50] qapi: add 'if' to top-level expressions Marc-André Lureau
@ 2017-09-11 11:05 ` Marc-André Lureau
2017-12-06 16:34 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 06/50] qapi: pass 'if' condition into QAPISchemaEntity objects Marc-André Lureau
` (46 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:05 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
tests/Makefile.include | 3 +++
tests/qapi-schema/bad-if-empty-list.err | 1 +
tests/qapi-schema/bad-if-empty-list.exit | 1 +
tests/qapi-schema/bad-if-empty-list.json | 3 +++
tests/qapi-schema/bad-if-empty-list.out | 0
tests/qapi-schema/bad-if-empty.err | 1 +
tests/qapi-schema/bad-if-empty.exit | 1 +
tests/qapi-schema/bad-if-empty.json | 3 +++
tests/qapi-schema/bad-if-empty.out | 0
tests/qapi-schema/bad-if.err | 1 +
tests/qapi-schema/bad-if.exit | 1 +
tests/qapi-schema/bad-if.json | 3 +++
tests/qapi-schema/bad-if.out | 0
13 files changed, 18 insertions(+)
create mode 100644 tests/qapi-schema/bad-if-empty-list.err
create mode 100644 tests/qapi-schema/bad-if-empty-list.exit
create mode 100644 tests/qapi-schema/bad-if-empty-list.json
create mode 100644 tests/qapi-schema/bad-if-empty-list.out
create mode 100644 tests/qapi-schema/bad-if-empty.err
create mode 100644 tests/qapi-schema/bad-if-empty.exit
create mode 100644 tests/qapi-schema/bad-if-empty.json
create mode 100644 tests/qapi-schema/bad-if-empty.out
create mode 100644 tests/qapi-schema/bad-if.err
create mode 100644 tests/qapi-schema/bad-if.exit
create mode 100644 tests/qapi-schema/bad-if.json
create mode 100644 tests/qapi-schema/bad-if.out
diff --git a/tests/Makefile.include b/tests/Makefile.include
index fae5715e9c..8dac7c9083 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -402,6 +402,9 @@ qapi-schema += args-unknown.json
qapi-schema += bad-base.json
qapi-schema += bad-data.json
qapi-schema += bad-ident.json
+qapi-schema += bad-if.json
+qapi-schema += bad-if-empty.json
+qapi-schema += bad-if-empty-list.json
qapi-schema += bad-type-bool.json
qapi-schema += bad-type-dict.json
qapi-schema += bad-type-int.json
diff --git a/tests/qapi-schema/bad-if-empty-list.err b/tests/qapi-schema/bad-if-empty-list.err
new file mode 100644
index 0000000000..75fe6497bc
--- /dev/null
+++ b/tests/qapi-schema/bad-if-empty-list.err
@@ -0,0 +1 @@
+tests/qapi-schema/bad-if-empty-list.json:2: 'if' condition [] is useless
diff --git a/tests/qapi-schema/bad-if-empty-list.exit b/tests/qapi-schema/bad-if-empty-list.exit
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/tests/qapi-schema/bad-if-empty-list.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/bad-if-empty-list.json b/tests/qapi-schema/bad-if-empty-list.json
new file mode 100644
index 0000000000..94f2eb8670
--- /dev/null
+++ b/tests/qapi-schema/bad-if-empty-list.json
@@ -0,0 +1,3 @@
+# check empty 'if' list
+{ 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
+ 'if': [] }
diff --git a/tests/qapi-schema/bad-if-empty-list.out b/tests/qapi-schema/bad-if-empty-list.out
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/qapi-schema/bad-if-empty.err b/tests/qapi-schema/bad-if-empty.err
new file mode 100644
index 0000000000..358bdc3e51
--- /dev/null
+++ b/tests/qapi-schema/bad-if-empty.err
@@ -0,0 +1 @@
+tests/qapi-schema/bad-if-empty.json:2: 'if' condition '' makes no sense
diff --git a/tests/qapi-schema/bad-if-empty.exit b/tests/qapi-schema/bad-if-empty.exit
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/tests/qapi-schema/bad-if-empty.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/bad-if-empty.json b/tests/qapi-schema/bad-if-empty.json
new file mode 100644
index 0000000000..fe1dd4eca6
--- /dev/null
+++ b/tests/qapi-schema/bad-if-empty.json
@@ -0,0 +1,3 @@
+# check empty 'if'
+{ 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
+ 'if': '' }
diff --git a/tests/qapi-schema/bad-if-empty.out b/tests/qapi-schema/bad-if-empty.out
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/qapi-schema/bad-if.err b/tests/qapi-schema/bad-if.err
new file mode 100644
index 0000000000..c2e3f5f44c
--- /dev/null
+++ b/tests/qapi-schema/bad-if.err
@@ -0,0 +1 @@
+tests/qapi-schema/bad-if.json:2: 'if' condition must be a string or a list of strings
diff --git a/tests/qapi-schema/bad-if.exit b/tests/qapi-schema/bad-if.exit
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/tests/qapi-schema/bad-if.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/bad-if.json b/tests/qapi-schema/bad-if.json
new file mode 100644
index 0000000000..3edd1a0bf2
--- /dev/null
+++ b/tests/qapi-schema/bad-if.json
@@ -0,0 +1,3 @@
+# check invalid 'if' type
+{ 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
+ 'if': { 'value': 'defined(TEST_IF_STRUCT)' } }
diff --git a/tests/qapi-schema/bad-if.out b/tests/qapi-schema/bad-if.out
new file mode 100644
index 0000000000..e69de29bb2
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 06/50] qapi: pass 'if' condition into QAPISchemaEntity objects
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (4 preceding siblings ...)
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 05/50] qapi: add tests for invalid 'if' Marc-André Lureau
@ 2017-09-11 11:05 ` Marc-André Lureau
2017-12-06 17:13 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 07/50] qapi: add 'ifcond' to visitor methods Marc-André Lureau
` (45 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:05 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
Built-in objects remain unconditional. Explicitly defined objects
use the condition specified in the schema. Implicitly defined
objects inherit their condition from their users. For most of them,
there is exactly one user, so the condition to use is obvious. The
exception is the wrapper types generated for simple union variants,
which can be shared by any number of simple unions. The tight
condition would be the disjunction of the conditions of these simple
unions. For now, use wrapped type's condition instead. Much
simpler and good enough for now.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi.py | 89 ++++++++++++++++++++++++++++++++++++---------------------
1 file changed, 57 insertions(+), 32 deletions(-)
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 20c1abf915..0f55caa18d 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -1000,7 +1000,7 @@ def check_exprs(exprs):
#
class QAPISchemaEntity(object):
- def __init__(self, name, info, doc):
+ def __init__(self, name, info, doc, ifcond=None):
assert isinstance(name, str)
self.name = name
# For explicitly defined entities, info points to the (explicit)
@@ -1010,6 +1010,7 @@ class QAPISchemaEntity(object):
# such place).
self.info = info
self.doc = doc
+ self.ifcond = ifcond
def c_name(self):
return c_name(self.name)
@@ -1126,8 +1127,8 @@ class QAPISchemaBuiltinType(QAPISchemaType):
class QAPISchemaEnumType(QAPISchemaType):
- def __init__(self, name, info, doc, values, prefix):
- QAPISchemaType.__init__(self, name, info, doc)
+ def __init__(self, name, info, doc, ifcond, values, prefix):
+ QAPISchemaType.__init__(self, name, info, doc, ifcond)
for v in values:
assert isinstance(v, QAPISchemaMember)
v.set_owner(name)
@@ -1162,7 +1163,7 @@ class QAPISchemaEnumType(QAPISchemaType):
class QAPISchemaArrayType(QAPISchemaType):
def __init__(self, name, info, element_type):
- QAPISchemaType.__init__(self, name, info, None)
+ QAPISchemaType.__init__(self, name, info, None, None)
assert isinstance(element_type, str)
self._element_type_name = element_type
self.element_type = None
@@ -1170,6 +1171,7 @@ class QAPISchemaArrayType(QAPISchemaType):
def check(self, schema):
self.element_type = schema.lookup_type(self._element_type_name)
assert self.element_type
+ self.ifcond = self.element_type.ifcond
def is_implicit(self):
return True
@@ -1191,11 +1193,12 @@ class QAPISchemaArrayType(QAPISchemaType):
class QAPISchemaObjectType(QAPISchemaType):
- def __init__(self, name, info, doc, base, local_members, variants):
+ def __init__(self, name, info, doc, ifcond,
+ base, local_members, variants):
# struct has local_members, optional base, and no variants
# flat union has base, variants, and no local_members
# simple union has local_members, variants, and no base
- QAPISchemaType.__init__(self, name, info, doc)
+ QAPISchemaType.__init__(self, name, info, doc, ifcond)
assert base is None or isinstance(base, str)
for m in local_members:
assert isinstance(m, QAPISchemaObjectTypeMember)
@@ -1383,8 +1386,8 @@ class QAPISchemaObjectTypeVariant(QAPISchemaObjectTypeMember):
class QAPISchemaAlternateType(QAPISchemaType):
- def __init__(self, name, info, doc, variants):
- QAPISchemaType.__init__(self, name, info, doc)
+ def __init__(self, name, info, doc, ifcond, variants):
+ QAPISchemaType.__init__(self, name, info, doc, ifcond)
assert isinstance(variants, QAPISchemaObjectTypeVariants)
assert variants.tag_member
variants.set_owner(name)
@@ -1420,9 +1423,9 @@ class QAPISchemaAlternateType(QAPISchemaType):
class QAPISchemaCommand(QAPISchemaEntity):
- def __init__(self, name, info, doc, arg_type, ret_type,
+ def __init__(self, name, info, doc, ifcond, arg_type, ret_type,
gen, success_response, boxed):
- QAPISchemaEntity.__init__(self, name, info, doc)
+ QAPISchemaEntity.__init__(self, name, info, doc, ifcond)
assert not arg_type or isinstance(arg_type, str)
assert not ret_type or isinstance(ret_type, str)
self._arg_type_name = arg_type
@@ -1459,8 +1462,8 @@ class QAPISchemaCommand(QAPISchemaEntity):
class QAPISchemaEvent(QAPISchemaEntity):
- def __init__(self, name, info, doc, arg_type, boxed):
- QAPISchemaEntity.__init__(self, name, info, doc)
+ def __init__(self, name, info, doc, ifcond, arg_type, boxed):
+ QAPISchemaEntity.__init__(self, name, info, doc, ifcond)
assert not arg_type or isinstance(arg_type, str)
self._arg_type_name = arg_type
self.arg_type = None
@@ -1544,22 +1547,22 @@ class QAPISchema(object):
('null', 'null', 'QNull' + pointer_suffix)]:
self._def_builtin_type(*t)
self.the_empty_object_type = QAPISchemaObjectType(
- 'q_empty', None, None, None, [], None)
+ 'q_empty', None, None, None, None, [], None)
self._def_entity(self.the_empty_object_type)
qtype_values = self._make_enum_members(['none', 'qnull', 'qnum',
'qstring', 'qdict', 'qlist',
'qbool'])
- self._def_entity(QAPISchemaEnumType('QType', None, None,
+ self._def_entity(QAPISchemaEnumType('QType', None, None, None,
qtype_values, 'QTYPE'))
def _make_enum_members(self, values):
return [QAPISchemaMember(v) for v in values]
- def _make_implicit_enum_type(self, name, info, values):
+ def _make_implicit_enum_type(self, name, info, ifcond, values):
# See also QAPISchemaObjectTypeMember._pretty_owner()
name = name + 'Kind' # Use namespace reserved by add_name()
self._def_entity(QAPISchemaEnumType(
- name, info, None, self._make_enum_members(values), None))
+ name, info, None, ifcond, self._make_enum_members(values), None))
return name
def _make_array_type(self, element_type, info):
@@ -1568,22 +1571,37 @@ class QAPISchema(object):
self._def_entity(QAPISchemaArrayType(name, info, element_type))
return name
- def _make_implicit_object_type(self, name, info, doc, role, members):
+ def _make_implicit_object_type(self, name, info, doc, ifcond,
+ role, members):
if not members:
return None
# See also QAPISchemaObjectTypeMember._pretty_owner()
name = 'q_obj_%s-%s' % (name, role)
- if not self.lookup_entity(name, QAPISchemaObjectType):
- self._def_entity(QAPISchemaObjectType(name, info, doc, None,
- members, None))
+ typ = self.lookup_entity(name, QAPISchemaObjectType)
+ if typ:
+ # The implicit object type has multiple users. This can
+ # happen only for simple unions' implicit wrapper types.
+ # Its ifcond should be the disjunction of its user's
+ # ifconds. Not implemented. Instead, we always pass the
+ # wrapped type's ifcond, which is trivially the same for all
+ # users. It's also necessary for the wrapper to compile.
+ # But it's not tight: the disjunction need not imply it. We
+ # may end up compiling useless wrapper types.
+ # TODO kill simple unions or implement the disjunction
+ assert ifcond == typ.ifcond
+ else:
+ self._def_entity(QAPISchemaObjectType(name, info, doc, ifcond,
+ None, members, None))
return name
def _def_enum_type(self, expr, info, doc):
name = expr['enum']
data = expr['data']
prefix = expr.get('prefix')
+ ifcond = expr.get('if')
self._def_entity(QAPISchemaEnumType(
- name, info, doc, self._make_enum_members(data), prefix))
+ name, info, doc, ifcond,
+ self._make_enum_members(data), prefix))
def _make_member(self, name, typ, info):
optional = False
@@ -1603,7 +1621,8 @@ class QAPISchema(object):
name = expr['struct']
base = expr.get('base')
data = expr['data']
- self._def_entity(QAPISchemaObjectType(name, info, doc, base,
+ ifcond = expr.get('if')
+ self._def_entity(QAPISchemaObjectType(name, info, doc, ifcond, base,
self._make_members(data, info),
None))
@@ -1615,18 +1634,21 @@ class QAPISchema(object):
assert len(typ) == 1
typ = self._make_array_type(typ[0], info)
typ = self._make_implicit_object_type(
- typ, info, None, 'wrapper', [self._make_member('data', typ, info)])
+ typ, info, None, self.lookup_type(typ).ifcond,
+ 'wrapper', [self._make_member('data', typ, info)])
return QAPISchemaObjectTypeVariant(case, typ)
def _def_union_type(self, expr, info, doc):
name = expr['union']
data = expr['data']
base = expr.get('base')
+ ifcond = expr.get('if')
tag_name = expr.get('discriminator')
tag_member = None
if isinstance(base, dict):
- base = (self._make_implicit_object_type(
- name, info, doc, 'base', self._make_members(base, info)))
+ base = self._make_implicit_object_type(
+ name, info, doc, ifcond,
+ 'base', self._make_members(base, info))
if tag_name:
variants = [self._make_variant(key, value)
for (key, value) in data.iteritems()]
@@ -1634,12 +1656,12 @@ class QAPISchema(object):
else:
variants = [self._make_simple_variant(key, value, info)
for (key, value) in data.iteritems()]
- typ = self._make_implicit_enum_type(name, info,
+ typ = self._make_implicit_enum_type(name, info, ifcond,
[v.name for v in variants])
tag_member = QAPISchemaObjectTypeMember('type', typ, False)
members = [tag_member]
self._def_entity(
- QAPISchemaObjectType(name, info, doc, base, members,
+ QAPISchemaObjectType(name, info, doc, ifcond, base, members,
QAPISchemaObjectTypeVariants(tag_name,
tag_member,
variants)))
@@ -1647,11 +1669,12 @@ class QAPISchema(object):
def _def_alternate_type(self, expr, info, doc):
name = expr['alternate']
data = expr['data']
+ ifcond = expr.get('if')
variants = [self._make_variant(key, value)
for (key, value) in data.iteritems()]
tag_member = QAPISchemaObjectTypeMember('type', 'QType', False)
self._def_entity(
- QAPISchemaAlternateType(name, info, doc,
+ QAPISchemaAlternateType(name, info, doc, ifcond,
QAPISchemaObjectTypeVariants(None,
tag_member,
variants)))
@@ -1663,23 +1686,25 @@ class QAPISchema(object):
gen = expr.get('gen', True)
success_response = expr.get('success-response', True)
boxed = expr.get('boxed', False)
+ ifcond = expr.get('if')
if isinstance(data, OrderedDict):
data = self._make_implicit_object_type(
- name, info, doc, 'arg', self._make_members(data, info))
+ name, info, doc, ifcond, 'arg', self._make_members(data, info))
if isinstance(rets, list):
assert len(rets) == 1
rets = self._make_array_type(rets[0], info)
- self._def_entity(QAPISchemaCommand(name, info, doc, data, rets,
+ self._def_entity(QAPISchemaCommand(name, info, doc, ifcond, data, rets,
gen, success_response, boxed))
def _def_event(self, expr, info, doc):
name = expr['event']
data = expr.get('data')
boxed = expr.get('boxed', False)
+ ifcond = expr.get('if')
if isinstance(data, OrderedDict):
data = self._make_implicit_object_type(
- name, info, doc, 'arg', self._make_members(data, info))
- self._def_entity(QAPISchemaEvent(name, info, doc, data, boxed))
+ name, info, doc, ifcond, 'arg', self._make_members(data, info))
+ self._def_entity(QAPISchemaEvent(name, info, doc, ifcond, data, boxed))
def _def_exprs(self):
for expr_elem in self.exprs:
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 07/50] qapi: add 'ifcond' to visitor methods
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (5 preceding siblings ...)
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 06/50] qapi: pass 'if' condition into QAPISchemaEntity objects Marc-André Lureau
@ 2017-09-11 11:05 ` Marc-André Lureau
2017-12-06 17:23 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 08/50] qapi: mcgen() shouldn't indent # lines Marc-André Lureau
` (44 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:05 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
Modify the test visitor to check correct passing of values.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi.py | 31 +++++++++++++++++--------------
scripts/qapi-commands.py | 2 +-
scripts/qapi-event.py | 2 +-
scripts/qapi-introspect.py | 12 ++++++------
scripts/qapi-types.py | 8 ++++----
scripts/qapi-visit.py | 8 ++++----
scripts/qapi2texi.py | 10 +++++-----
tests/qapi-schema/qapi-schema-test.out | 9 +++++++++
tests/qapi-schema/test-qapi.py | 21 ++++++++++++++++-----
9 files changed, 63 insertions(+), 40 deletions(-)
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 0f55caa18d..f2b5a7e131 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -1039,26 +1039,26 @@ class QAPISchemaVisitor(object):
def visit_builtin_type(self, name, info, json_type):
pass
- def visit_enum_type(self, name, info, values, prefix):
+ def visit_enum_type(self, name, info, ifcond, values, prefix):
pass
- def visit_array_type(self, name, info, element_type):
+ def visit_array_type(self, name, info, ifcond, element_type):
pass
- def visit_object_type(self, name, info, base, members, variants):
+ def visit_object_type(self, name, info, ifcond, base, members, variants):
pass
- def visit_object_type_flat(self, name, info, members, variants):
+ def visit_object_type_flat(self, name, info, ifcond, members, variants):
pass
- def visit_alternate_type(self, name, info, variants):
+ def visit_alternate_type(self, name, info, ifcond, variants):
pass
- def visit_command(self, name, info, arg_type, ret_type,
+ def visit_command(self, name, info, ifcond, arg_type, ret_type,
gen, success_response, boxed):
pass
- def visit_event(self, name, info, arg_type, boxed):
+ def visit_event(self, name, info, ifcond, arg_type, boxed):
pass
@@ -1157,7 +1157,7 @@ class QAPISchemaEnumType(QAPISchemaType):
return 'string'
def visit(self, visitor):
- visitor.visit_enum_type(self.name, self.info,
+ visitor.visit_enum_type(self.name, self.info, self.ifcond,
self.member_names(), self.prefix)
@@ -1189,7 +1189,8 @@ class QAPISchemaArrayType(QAPISchemaType):
return 'array of ' + elt_doc_type
def visit(self, visitor):
- visitor.visit_array_type(self.name, self.info, self.element_type)
+ visitor.visit_array_type(self.name, self.info, self.ifcond,
+ self.element_type)
class QAPISchemaObjectType(QAPISchemaType):
@@ -1270,9 +1271,9 @@ class QAPISchemaObjectType(QAPISchemaType):
return 'object'
def visit(self, visitor):
- visitor.visit_object_type(self.name, self.info,
+ visitor.visit_object_type(self.name, self.info, self.ifcond,
self.base, self.local_members, self.variants)
- visitor.visit_object_type_flat(self.name, self.info,
+ visitor.visit_object_type_flat(self.name, self.info, self.ifcond,
self.members, self.variants)
@@ -1416,7 +1417,8 @@ class QAPISchemaAlternateType(QAPISchemaType):
return 'value'
def visit(self, visitor):
- visitor.visit_alternate_type(self.name, self.info, self.variants)
+ visitor.visit_alternate_type(self.name, self.info, self.ifcond,
+ self.variants)
def is_empty(self):
return False
@@ -1456,7 +1458,7 @@ class QAPISchemaCommand(QAPISchemaEntity):
assert isinstance(self.ret_type, QAPISchemaType)
def visit(self, visitor):
- visitor.visit_command(self.name, self.info,
+ visitor.visit_command(self.name, self.info, self.ifcond,
self.arg_type, self.ret_type,
self.gen, self.success_response, self.boxed)
@@ -1486,7 +1488,8 @@ class QAPISchemaEvent(QAPISchemaEntity):
raise QAPISemError(self.info, "Use of 'boxed' requires 'data'")
def visit(self, visitor):
- visitor.visit_event(self.name, self.info, self.arg_type, self.boxed)
+ visitor.visit_event(self.name, self.info, self.ifcond,
+ self.arg_type, self.boxed)
class QAPISchema(object):
diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index 974d0a4a80..669aef1eb7 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -240,7 +240,7 @@ class QAPISchemaGenCommandVisitor(QAPISchemaVisitor):
self._regy = None
self._visited_ret_types = None
- def visit_command(self, name, info, arg_type, ret_type,
+ def visit_command(self, name, info, ifcond, arg_type, ret_type,
gen, success_response, boxed):
if not gen:
return
diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py
index 07b4b70199..dda496e824 100644
--- a/scripts/qapi-event.py
+++ b/scripts/qapi-event.py
@@ -163,7 +163,7 @@ class QAPISchemaGenEventVisitor(QAPISchemaVisitor):
self.defn += gen_enum_lookup(event_enum_name, self._event_names)
self._event_names = None
- def visit_event(self, name, info, arg_type, boxed):
+ def visit_event(self, name, info, ifcond, arg_type, boxed):
self.decl += gen_event_send_decl(name, arg_type, boxed)
self.defn += gen_event_send(name, arg_type, boxed)
self._event_names.append(name)
diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
index 0002bc1a68..56c1f9d548 100644
--- a/scripts/qapi-introspect.py
+++ b/scripts/qapi-introspect.py
@@ -142,26 +142,26 @@ const QLitObject %(c_name)s = %(c_string)s;
def visit_builtin_type(self, name, info, json_type):
self._gen_qlit(name, 'builtin', {'json-type': json_type})
- def visit_enum_type(self, name, info, values, prefix):
+ def visit_enum_type(self, name, info, ifcond, values, prefix):
self._gen_qlit(name, 'enum', {'values': values})
- def visit_array_type(self, name, info, element_type):
+ def visit_array_type(self, name, info, ifcond, element_type):
element = self._use_type(element_type)
self._gen_qlit('[' + element + ']', 'array', {'element-type': element})
- def visit_object_type_flat(self, name, info, members, variants):
+ def visit_object_type_flat(self, name, info, ifcond, 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_qlit(name, 'object', obj)
- def visit_alternate_type(self, name, info, variants):
+ def visit_alternate_type(self, name, info, ifcond, variants):
self._gen_qlit(name, 'alternate',
{'members': [{'type': self._use_type(m.type)}
for m in variants.variants]})
- def visit_command(self, name, info, arg_type, ret_type,
+ def visit_command(self, name, info, ifcond, arg_type, ret_type,
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
@@ -169,7 +169,7 @@ const QLitObject %(c_name)s = %(c_string)s;
{'arg-type': self._use_type(arg_type),
'ret-type': self._use_type(ret_type)})
- def visit_event(self, name, info, arg_type, boxed):
+ def visit_event(self, name, info, ifcond, arg_type, boxed):
arg_type = arg_type or self._schema.the_empty_object_type
self._gen_qlit(name, 'event', {'arg-type': self._use_type(arg_type)})
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 7e3051dbb9..915786c463 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -195,7 +195,7 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
self.decl += gen_type_cleanup_decl(name)
self.defn += gen_type_cleanup(name)
- def visit_enum_type(self, name, info, values, prefix):
+ def visit_enum_type(self, name, info, ifcond, values, prefix):
# Special case for our lone builtin enum type
# TODO use something cleaner than existence of info
if not info:
@@ -206,7 +206,7 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
self._fwdecl += gen_enum(name, values, prefix)
self.defn += gen_enum_lookup(name, values, prefix)
- def visit_array_type(self, name, info, element_type):
+ def visit_array_type(self, name, info, ifcond, element_type):
if isinstance(element_type, QAPISchemaBuiltinType):
self._btin += gen_fwd_object_or_array(name)
self._btin += gen_array(name, element_type)
@@ -218,7 +218,7 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
self.decl += gen_array(name, element_type)
self._gen_type_cleanup(name)
- def visit_object_type(self, name, info, base, members, variants):
+ def visit_object_type(self, name, info, ifcond, base, members, variants):
# Nothing to do for the special empty builtin
if name == 'q_empty':
return
@@ -232,7 +232,7 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
# implicit types won't be directly allocated/freed
self._gen_type_cleanup(name)
- def visit_alternate_type(self, name, info, variants):
+ def visit_alternate_type(self, name, info, ifcond, variants):
self._fwdecl += gen_fwd_object_or_array(name)
self.decl += gen_object(name, None, [variants.tag_member], variants)
self._gen_type_cleanup(name)
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 7e1cfc13f0..aceea2a9f9 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -282,7 +282,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
self.decl = self._btin + self.decl
self._btin = None
- def visit_enum_type(self, name, info, values, prefix):
+ def visit_enum_type(self, name, info, ifcond, values, prefix):
# Special case for our lone builtin enum type
# TODO use something cleaner than existence of info
if not info:
@@ -293,7 +293,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
self.decl += gen_visit_decl(name, scalar=True)
self.defn += gen_visit_enum(name)
- def visit_array_type(self, name, info, element_type):
+ def visit_array_type(self, name, info, ifcond, element_type):
decl = gen_visit_decl(name)
defn = gen_visit_list(name, element_type)
if isinstance(element_type, QAPISchemaBuiltinType):
@@ -304,7 +304,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
self.decl += decl
self.defn += defn
- def visit_object_type(self, name, info, base, members, variants):
+ def visit_object_type(self, name, info, ifcond, base, members, variants):
# Nothing to do for the special empty builtin
if name == 'q_empty':
return
@@ -317,7 +317,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
self.decl += gen_visit_decl(name)
self.defn += gen_visit_object(name, base, members, variants)
- def visit_alternate_type(self, name, info, variants):
+ def visit_alternate_type(self, name, info, ifcond, variants):
self.decl += gen_visit_decl(name)
self.defn += gen_visit_alternate(name, variants)
diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py
index 73cfb01727..cf63cb0006 100755
--- a/scripts/qapi2texi.py
+++ b/scripts/qapi2texi.py
@@ -207,7 +207,7 @@ class QAPISchemaGenDocVisitor(qapi.QAPISchemaVisitor):
def visit_begin(self, schema):
self.out = ''
- def visit_enum_type(self, name, info, values, prefix):
+ def visit_enum_type(self, name, info, ifcond, values, prefix):
doc = self.cur_doc
if self.out:
self.out += '\n'
@@ -216,7 +216,7 @@ class QAPISchemaGenDocVisitor(qapi.QAPISchemaVisitor):
body=texi_entity(doc, 'Values',
member_func=texi_enum_value))
- def visit_object_type(self, name, info, base, members, variants):
+ def visit_object_type(self, name, info, ifcond, base, members, variants):
doc = self.cur_doc
if base and base.is_implicit():
base = None
@@ -226,7 +226,7 @@ class QAPISchemaGenDocVisitor(qapi.QAPISchemaVisitor):
name=doc.symbol,
body=texi_entity(doc, 'Members', base, variants))
- def visit_alternate_type(self, name, info, variants):
+ def visit_alternate_type(self, name, info, ifcond, variants):
doc = self.cur_doc
if self.out:
self.out += '\n'
@@ -234,7 +234,7 @@ class QAPISchemaGenDocVisitor(qapi.QAPISchemaVisitor):
name=doc.symbol,
body=texi_entity(doc, 'Members'))
- def visit_command(self, name, info, arg_type, ret_type,
+ def visit_command(self, name, info, ifcond, arg_type, ret_type,
gen, success_response, boxed):
doc = self.cur_doc
if self.out:
@@ -249,7 +249,7 @@ class QAPISchemaGenDocVisitor(qapi.QAPISchemaVisitor):
name=doc.symbol,
body=body)
- def visit_event(self, name, info, arg_type, boxed):
+ def visit_event(self, name, info, ifcond, arg_type, boxed):
doc = self.cur_doc
if self.out:
self.out += '\n'
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index 7fbaea19bc..fc5fd25f1b 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -56,18 +56,25 @@ alternate TestIfAlternate
tag type
case foo: int
case bar: TestStruct
+ if defined(TEST_IF_ALT) && defined(TEST_IF_STRUCT)
command TestIfCmd q_obj_TestIfCmd-arg -> None
gen=True success_response=True boxed=False
+ if defined(TEST_IF_CMD) && defined(TEST_IF_STRUCT)
enum TestIfEnum ['foo', 'bar']
+ if defined(TEST_IF_ENUM)
event TestIfEvent q_obj_TestIfEvent-arg
boxed=False
+ if defined(TEST_IF_EVT) && defined(TEST_IF_STRUCT)
object TestIfStruct
member foo: int optional=False
+ if defined(TEST_IF_STRUCT)
object TestIfUnion
member type: TestIfUnionKind optional=False
tag type
case foo: q_obj_TestStruct-wrapper
+ if defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)
enum TestIfUnionKind ['foo']
+ if defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)
object TestStruct
member integer: int optional=False
member boolean: bool optional=False
@@ -190,8 +197,10 @@ object q_obj_EVENT_D-arg
member enum3: EnumOne optional=True
object q_obj_TestIfCmd-arg
member foo: TestIfStruct optional=False
+ if defined(TEST_IF_CMD) && defined(TEST_IF_STRUCT)
object q_obj_TestIfEvent-arg
member foo: TestIfStruct optional=False
+ if defined(TEST_IF_EVT) && defined(TEST_IF_STRUCT)
object q_obj_TestStruct-wrapper
member data: TestStruct optional=False
object q_obj_UserDefFlatUnion2-base
diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
index c7724d3437..8627f978af 100644
--- a/tests/qapi-schema/test-qapi.py
+++ b/tests/qapi-schema/test-qapi.py
@@ -17,12 +17,13 @@ import sys
class QAPISchemaTestVisitor(QAPISchemaVisitor):
- def visit_enum_type(self, name, info, values, prefix):
+ def visit_enum_type(self, name, info, ifcond, values, prefix):
print 'enum %s %s' % (name, values)
if prefix:
print ' prefix %s' % prefix
+ self._print_if(ifcond)
- def visit_object_type(self, name, info, base, members, variants):
+ def visit_object_type(self, name, info, ifcond, base, members, variants):
print 'object %s' % name
if base:
print ' base %s' % base.name
@@ -30,21 +31,25 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
print ' member %s: %s optional=%s' % \
(m.name, m.type.name, m.optional)
self._print_variants(variants)
+ self._print_if(ifcond)
- def visit_alternate_type(self, name, info, variants):
+ def visit_alternate_type(self, name, info, ifcond, variants):
print 'alternate %s' % name
self._print_variants(variants)
+ self._print_if(ifcond)
- def visit_command(self, name, info, arg_type, ret_type,
+ def visit_command(self, name, info, ifcond, arg_type, ret_type,
gen, success_response, boxed):
print 'command %s %s -> %s' % \
(name, arg_type and arg_type.name, ret_type and ret_type.name)
print ' gen=%s success_response=%s boxed=%s' % \
(gen, success_response, boxed)
+ self._print_if(ifcond)
- def visit_event(self, name, info, arg_type, boxed):
+ def visit_event(self, name, info, ifcond, arg_type, boxed):
print 'event %s %s' % (name, arg_type and arg_type.name)
print ' boxed=%s' % boxed
+ self._print_if(ifcond)
@staticmethod
def _print_variants(variants):
@@ -53,6 +58,12 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
for v in variants.variants:
print ' case %s: %s' % (v.name, v.type.name)
+ @staticmethod
+ def _print_if(ifcond):
+ if ifcond:
+ print ' if %s' % ifcond
+
+
schema = QAPISchema(sys.argv[1])
schema.visit(QAPISchemaTestVisitor())
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 08/50] qapi: mcgen() shouldn't indent # lines
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (6 preceding siblings ...)
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 07/50] qapi: add 'ifcond' to visitor methods Marc-André Lureau
@ 2017-09-11 11:05 ` Marc-André Lureau
2017-12-06 17:41 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 09/50] qapi: add #if/#endif helpers Marc-André Lureau
` (43 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:05 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
Skip preprocessor lines when adding indentation, since that would
likely result in invalid code.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/qapi.py b/scripts/qapi.py
index f2b5a7e131..2a8e60e975 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -1862,7 +1862,7 @@ def cgen(code, **kwds):
if indent_level:
indent = genindent(indent_level)
# re.subn() lacks flags support before Python 2.7, use re.compile()
- raw = re.subn(re.compile(r'^.', re.MULTILINE),
+ raw = re.subn(re.compile(r'^[^#\n].', re.MULTILINE),
indent + r'\g<0>', raw)
raw = raw[0]
return re.sub(re.escape(eatspace) + r' *', '', raw)
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 09/50] qapi: add #if/#endif helpers
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (7 preceding siblings ...)
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 08/50] qapi: mcgen() shouldn't indent # lines Marc-André Lureau
@ 2017-09-11 11:05 ` Marc-André Lureau
2017-12-07 14:10 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 10/50] qapi-introspect: modify to_qlit() to append ', ' on level > 0 Marc-André Lureau
` (42 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:05 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
Add helpers to wrap generated code with #if/#endif lines.
Add a function decorator that will be used to wrap visitor methods.
The decorator will check if code was generated before adding #if/#endif
lines. Used in the following patches.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi.py | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 2a8e60e975..94b735d8d6 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -1897,6 +1897,61 @@ def guardend(name):
name=guardname(name))
+def gen_if(ifcond):
+ if not ifcond:
+ return ''
+ if isinstance(ifcond, str):
+ ifcond = [ifcond]
+ ret = ''
+ for ifc in ifcond:
+ ret += mcgen('''
+#if %(cond)s
+''', cond=ifc)
+ return ret
+
+
+def gen_endif(ifcond):
+ if not ifcond:
+ return ''
+ if isinstance(ifcond, str):
+ ifcond = [ifcond]
+ ret = ''
+ for ifc in reversed(ifcond):
+ ret += mcgen('''
+#endif /* %(cond)s */
+''', cond=ifc)
+ return ret
+
+
+# Wrap a method to add #if / #endif to generated code, only if some
+# code was generated. The method must have an 'ifcond' argument.
+# self must have 'if_members' listing the attributes to wrap.
+def ifcond_decorator(func):
+
+ def func_wrapper(self, *args, **kwargs):
+ import inspect
+ idx = inspect.getargspec(func).args.index('ifcond')
+ ifcond = args[idx - 1]
+ save = {}
+ for mem in self.if_members:
+ save[mem] = getattr(self, mem)
+ func(self, *args, **kwargs)
+ for mem, val in save.items():
+ newval = getattr(self, mem)
+ if newval != val:
+ assert newval.startswith(val)
+ newval = newval[len(val):]
+ if newval[0] == '\n':
+ val += '\n'
+ newval = newval[1:]
+ val += gen_if(ifcond)
+ val += newval
+ val += gen_endif(ifcond)
+ setattr(self, mem, val)
+
+ return func_wrapper
+
+
def gen_enum_lookup(name, values, prefix=None):
ret = mcgen('''
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 10/50] qapi-introspect: modify to_qlit() to append ', ' on level > 0
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (8 preceding siblings ...)
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 09/50] qapi: add #if/#endif helpers Marc-André Lureau
@ 2017-09-11 11:05 ` Marc-André Lureau
2017-12-07 14:47 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 11/50] qapi-introspect: modify to_qlit() to generate #if code Marc-André Lureau
` (41 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:05 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
The following patch is going to break list entries with #if/#endif, so
they should have the trailing ',' as suffix.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi-introspect.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
index 56c1f9d548..b1d08ec97b 100644
--- a/scripts/qapi-introspect.py
+++ b/scripts/qapi-introspect.py
@@ -29,7 +29,7 @@ def to_qlit(obj, level=0, suppress_first_indent=False):
for elt in obj]
elts.append(indent(level + 1) + "{}")
ret += 'QLIT_QLIST(((QLitObject[]) {\n'
- ret += ',\n'.join(elts) + '\n'
+ ret += '\n'.join(elts) + '\n'
ret += indent(level) + '}))'
elif isinstance(obj, dict):
elts = []
@@ -42,6 +42,8 @@ def to_qlit(obj, level=0, suppress_first_indent=False):
ret += indent(level) + '}))'
else:
assert False # not implemented
+ if level > 0:
+ ret += ','
return ret
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 11/50] qapi-introspect: modify to_qlit() to generate #if code
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (9 preceding siblings ...)
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 10/50] qapi-introspect: modify to_qlit() to append ', ' on level > 0 Marc-André Lureau
@ 2017-09-11 11:05 ` Marc-André Lureau
2017-12-07 14:50 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 12/50] qapi-introspect: add preprocessor conditions to generated QLit Marc-André Lureau
` (40 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:05 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
The generator now accepts (obj, condition) tuples to wrap generated
QLit objects for 'obj' with #if/#endif conditions.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi-introspect.py | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
index b1d08ec97b..dc70954e8a 100644
--- a/scripts/qapi-introspect.py
+++ b/scripts/qapi-introspect.py
@@ -17,6 +17,13 @@ def to_qlit(obj, level=0, suppress_first_indent=False):
def indent(level):
return level * 4 * ' '
+ if isinstance(obj, tuple):
+ ifobj, ifcond = obj
+ ret = gen_if(ifcond)
+ ret += to_qlit(ifobj, level)
+ ret += '\n' + gen_endif(ifcond)
+ return ret
+
ret = ''
if not suppress_first_indent:
ret += indent(level)
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 12/50] qapi-introspect: add preprocessor conditions to generated QLit
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (10 preceding siblings ...)
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 11/50] qapi-introspect: modify to_qlit() to generate #if code Marc-André Lureau
@ 2017-09-11 11:05 ` Marc-André Lureau
2017-12-07 15:41 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 13/50] qapi-commands: add #if conditions to commands Marc-André Lureau
` (39 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:05 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
Add 'ifcond' condition to top-level QLit objects.
to_qlit() handles the (obj, ifcond) tuples in previous patch.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi-introspect.py | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
index dc70954e8a..69d9afc792 100644
--- a/scripts/qapi-introspect.py
+++ b/scripts/qapi-introspect.py
@@ -128,12 +128,12 @@ const QLitObject %(c_name)s = %(c_string)s;
return '[' + self._use_type(typ.element_type) + ']'
return self._name(typ.name)
- def _gen_qlit(self, name, mtype, obj):
+ def _gen_qlit(self, name, mtype, obj, ifcond):
if mtype not in ('command', 'event', 'builtin', 'array'):
name = self._name(name)
obj['name'] = name
obj['meta-type'] = mtype
- self._qlits.append(obj)
+ self._qlits.append((obj, ifcond))
def _gen_member(self, member):
ret = {'name': member.name, 'type': self._use_type(member.type)}
@@ -149,26 +149,27 @@ const QLitObject %(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_qlit(name, 'builtin', {'json-type': json_type})
+ self._gen_qlit(name, 'builtin', {'json-type': json_type}, None)
def visit_enum_type(self, name, info, ifcond, values, prefix):
- self._gen_qlit(name, 'enum', {'values': values})
+ self._gen_qlit(name, 'enum', {'values': values}, ifcond)
def visit_array_type(self, name, info, ifcond, element_type):
element = self._use_type(element_type)
- self._gen_qlit('[' + element + ']', 'array', {'element-type': element})
+ self._gen_qlit('[' + element + ']', 'array', {'element-type': element},
+ ifcond)
def visit_object_type_flat(self, name, info, ifcond, 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_qlit(name, 'object', obj)
+ self._gen_qlit(name, 'object', obj, ifcond)
def visit_alternate_type(self, name, info, ifcond, variants):
self._gen_qlit(name, 'alternate',
{'members': [{'type': self._use_type(m.type)}
- for m in variants.variants]})
+ for m in variants.variants]}, ifcond)
def visit_command(self, name, info, ifcond, arg_type, ret_type,
gen, success_response, boxed):
@@ -176,11 +177,12 @@ const QLitObject %(c_name)s = %(c_string)s;
ret_type = ret_type or self._schema.the_empty_object_type
self._gen_qlit(name, 'command',
{'arg-type': self._use_type(arg_type),
- 'ret-type': self._use_type(ret_type)})
+ 'ret-type': self._use_type(ret_type)}, ifcond)
def visit_event(self, name, info, ifcond, arg_type, boxed):
arg_type = arg_type or self._schema.the_empty_object_type
- self._gen_qlit(name, 'event', {'arg-type': self._use_type(arg_type)})
+ self._gen_qlit(name, 'event', {'arg-type': self._use_type(arg_type)},
+ ifcond)
# Debugging aid: unmask QAPI schema's type names
# We normally mask them, because they're not QMP wire ABI
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 13/50] qapi-commands: add #if conditions to commands
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (11 preceding siblings ...)
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 12/50] qapi-introspect: add preprocessor conditions to generated QLit Marc-André Lureau
@ 2017-09-11 11:05 ` Marc-André Lureau
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 14/50] qapi-event: add #if conditions to events Marc-André Lureau
` (38 subsequent siblings)
51 siblings, 0 replies; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:05 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
Wrap generated code with #if/#endif using the ifcond_decorator.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi-commands.py | 2 ++
tests/test-qmp-commands.c | 4 ++--
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index 669aef1eb7..8af8d913b9 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -228,6 +228,7 @@ class QAPISchemaGenCommandVisitor(QAPISchemaVisitor):
self.defn = None
self._regy = None
self._visited_ret_types = None
+ self.if_members = ['decl', 'defn', '_regy']
def visit_begin(self, schema):
self.decl = ''
@@ -240,6 +241,7 @@ class QAPISchemaGenCommandVisitor(QAPISchemaVisitor):
self._regy = None
self._visited_ret_types = None
+ @ifcond_decorator
def visit_command(self, name, info, ifcond, arg_type, ret_type,
gen, success_response, boxed):
if not gen:
diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c
index 9b9a7ffee7..ad7b6e4e1d 100644
--- a/tests/test-qmp-commands.c
+++ b/tests/test-qmp-commands.c
@@ -10,11 +10,11 @@
static QmpCommandList qmp_commands;
-/* #if defined(TEST_IF_CMD) */
+#if defined(TEST_IF_CMD)
void qmp_TestIfCmd(TestIfStruct *foo, Error **errp)
{
}
-/* #endif */
+#endif
void qmp_user_def_cmd(Error **errp)
{
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 14/50] qapi-event: add #if conditions to events
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (12 preceding siblings ...)
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 13/50] qapi-commands: add #if conditions to commands Marc-André Lureau
@ 2017-09-11 11:05 ` Marc-André Lureau
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 15/50] qapi-types: refactor variants handling Marc-André Lureau
` (37 subsequent siblings)
51 siblings, 0 replies; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:05 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
Wrap generated code with #if/#endif using the ifcond_decorator.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi-event.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py
index dda496e824..bef301dfe9 100644
--- a/scripts/qapi-event.py
+++ b/scripts/qapi-event.py
@@ -152,6 +152,7 @@ class QAPISchemaGenEventVisitor(QAPISchemaVisitor):
self.decl = None
self.defn = None
self._event_names = None
+ self.if_members = ['decl', 'defn']
def visit_begin(self, schema):
self.decl = ''
@@ -163,6 +164,7 @@ class QAPISchemaGenEventVisitor(QAPISchemaVisitor):
self.defn += gen_enum_lookup(event_enum_name, self._event_names)
self._event_names = None
+ @ifcond_decorator
def visit_event(self, name, info, ifcond, arg_type, boxed):
self.decl += gen_event_send_decl(name, arg_type, boxed)
self.defn += gen_event_send(name, arg_type, boxed)
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 15/50] qapi-types: refactor variants handling
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (13 preceding siblings ...)
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 14/50] qapi-event: add #if conditions to events Marc-André Lureau
@ 2017-09-11 11:05 ` Marc-André Lureau
2017-12-07 15:57 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 16/50] qapi-types: add #if conditions to types & visitors Marc-André Lureau
` (36 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:05 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
Generate variants objects outside gen_object(). This will allow to
easily wrap gen_object() with ifcond_decorator in the following patch.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi-types.py | 37 +++++++++++++++++++++++--------------
1 file changed, 23 insertions(+), 14 deletions(-)
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 915786c463..2b3588267b 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -53,23 +53,27 @@ def gen_struct_members(members):
return ret
-def gen_object(name, base, members, variants):
- if name in objects_seen:
- return ''
- objects_seen.add(name)
-
+def gen_variants_objects(variants):
ret = ''
if variants:
for v in variants.variants:
if isinstance(v.type, QAPISchemaObjectType):
+ ret += gen_variants_objects(v.type.variants)
ret += gen_object(v.type.name, v.type.base,
v.type.local_members, v.type.variants)
+ return ret
- ret += mcgen('''
+
+def gen_object(name, base, members, variants):
+ if name in objects_seen:
+ return ''
+ objects_seen.add(name)
+
+ ret = mcgen('''
struct %(c_name)s {
''',
- c_name=c_name(name))
+ c_name=c_name(name))
if base:
if not base.is_implicit():
@@ -218,11 +222,7 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
self.decl += gen_array(name, element_type)
self._gen_type_cleanup(name)
- def visit_object_type(self, name, info, ifcond, base, members, variants):
- # Nothing to do for the special empty builtin
- if name == 'q_empty':
- return
- self._fwdecl += gen_fwd_object_or_array(name)
+ def _gen_object(self, name, info, ifcond, base, members, variants):
self.decl += gen_object(name, base, members, variants)
if base and not base.is_implicit():
self.decl += gen_upcast(name, base)
@@ -232,10 +232,19 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
# implicit types won't be directly allocated/freed
self._gen_type_cleanup(name)
+ def visit_object_type(self, name, info, ifcond, base, members, variants):
+ # Nothing to do for the special empty builtin
+ if name == 'q_empty':
+ return
+ self._fwdecl += gen_fwd_object_or_array(name)
+ self.decl += gen_variants_objects(variants)
+ self._gen_object(name, info, None, base, members, variants)
+
def visit_alternate_type(self, name, info, ifcond, variants):
self._fwdecl += gen_fwd_object_or_array(name)
- self.decl += gen_object(name, None, [variants.tag_member], variants)
- self._gen_type_cleanup(name)
+ self.decl += gen_variants_objects(variants)
+ self._gen_object(name, info, None, None,
+ [variants.tag_member], variants)
# If you link code generated from multiple schemata, you want only one
# instance of the code for built-in types. Generate it only when
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 16/50] qapi-types: add #if conditions to types & visitors
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (14 preceding siblings ...)
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 15/50] qapi-types: refactor variants handling Marc-André Lureau
@ 2017-09-11 11:05 ` Marc-André Lureau
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 17/50] qapi: do not define enumeration value explicitely Marc-André Lureau
` (35 subsequent siblings)
51 siblings, 0 replies; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:05 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
Types & visitors are coupled and must be handled together to avoid
temporary build regression.
Wrap generated types/visitor code with #if/#endif using the
ifcond_decorator & helpers.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi-types.py | 18 ++++++++++++++----
scripts/qapi-visit.py | 5 +++++
2 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 2b3588267b..789e89ff59 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -59,8 +59,10 @@ def gen_variants_objects(variants):
for v in variants.variants:
if isinstance(v.type, QAPISchemaObjectType):
ret += gen_variants_objects(v.type.variants)
+ ret += gen_if(v.type.ifcond)
ret += gen_object(v.type.name, v.type.base,
v.type.local_members, v.type.variants)
+ ret += gen_endif(v.type.ifcond)
return ret
@@ -175,6 +177,7 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
self.defn = None
self._fwdecl = None
self._btin = None
+ self.if_members = ['decl', 'defn', '_fwdecl', '_btin']
def visit_begin(self, schema):
# gen_object() is recursive, ensure it doesn't visit the empty type
@@ -199,6 +202,7 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
self.decl += gen_type_cleanup_decl(name)
self.defn += gen_type_cleanup(name)
+ @ifcond_decorator
def visit_enum_type(self, name, info, ifcond, values, prefix):
# Special case for our lone builtin enum type
# TODO use something cleaner than existence of info
@@ -210,6 +214,7 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
self._fwdecl += gen_enum(name, values, prefix)
self.defn += gen_enum_lookup(name, values, prefix)
+ @ifcond_decorator
def visit_array_type(self, name, info, ifcond, element_type):
if isinstance(element_type, QAPISchemaBuiltinType):
self._btin += gen_fwd_object_or_array(name)
@@ -222,6 +227,7 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
self.decl += gen_array(name, element_type)
self._gen_type_cleanup(name)
+ @ifcond_decorator
def _gen_object(self, name, info, ifcond, base, members, variants):
self.decl += gen_object(name, base, members, variants)
if base and not base.is_implicit():
@@ -232,18 +238,22 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
# implicit types won't be directly allocated/freed
self._gen_type_cleanup(name)
+ @ifcond_decorator
+ def _gen_fwd_object_or_array(self, name, ifcond):
+ self._fwdecl += gen_fwd_object_or_array(name)
+
def visit_object_type(self, name, info, ifcond, base, members, variants):
# Nothing to do for the special empty builtin
if name == 'q_empty':
return
- self._fwdecl += gen_fwd_object_or_array(name)
+ self._gen_fwd_object_or_array(name, ifcond)
self.decl += gen_variants_objects(variants)
- self._gen_object(name, info, None, base, members, variants)
+ self._gen_object(name, info, ifcond, base, members, variants)
def visit_alternate_type(self, name, info, ifcond, variants):
- self._fwdecl += gen_fwd_object_or_array(name)
+ self._gen_fwd_object_or_array(name, ifcond)
self.decl += gen_variants_objects(variants)
- self._gen_object(name, info, None, None,
+ self._gen_object(name, info, ifcond, None,
[variants.tag_member], variants)
# If you link code generated from multiple schemata, you want only one
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index aceea2a9f9..4b0e005437 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -267,6 +267,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
self.decl = None
self.defn = None
self._btin = None
+ self.if_members = ['decl', 'defn', '_btin']
def visit_begin(self, schema):
self.decl = ''
@@ -282,6 +283,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
self.decl = self._btin + self.decl
self._btin = None
+ @ifcond_decorator
def visit_enum_type(self, name, info, ifcond, values, prefix):
# Special case for our lone builtin enum type
# TODO use something cleaner than existence of info
@@ -293,6 +295,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
self.decl += gen_visit_decl(name, scalar=True)
self.defn += gen_visit_enum(name)
+ @ifcond_decorator
def visit_array_type(self, name, info, ifcond, element_type):
decl = gen_visit_decl(name)
defn = gen_visit_list(name, element_type)
@@ -304,6 +307,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
self.decl += decl
self.defn += defn
+ @ifcond_decorator
def visit_object_type(self, name, info, ifcond, base, members, variants):
# Nothing to do for the special empty builtin
if name == 'q_empty':
@@ -317,6 +321,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
self.decl += gen_visit_decl(name)
self.defn += gen_visit_object(name, base, members, variants)
+ @ifcond_decorator
def visit_alternate_type(self, name, info, ifcond, variants):
self.decl += gen_visit_decl(name)
self.defn += gen_visit_alternate(name, variants)
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 17/50] qapi: do not define enumeration value explicitely
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (15 preceding siblings ...)
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 16/50] qapi-types: add #if conditions to types & visitors Marc-André Lureau
@ 2017-09-11 11:05 ` Marc-André Lureau
2017-12-07 16:23 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 18/50] qapi: change enum visitor to take QAPISchemaMember Marc-André Lureau
` (34 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:05 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
The C standard has the initial value at 0 and the subsequent values
incremented by 1. No need to set this explicitely.
This will prevent from artificial "gaps" when compiling out some enum
values and having unnecessarily large MAX values & enums arrays.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi.py | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 94b735d8d6..074ee221a1 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -1985,14 +1985,11 @@ typedef enum %(c_name)s {
''',
c_name=c_name(name))
- i = 0
for value in enum_values:
ret += mcgen('''
- %(c_enum)s = %(i)d,
+ %(c_enum)s,
''',
- c_enum=c_enum_const(name, value, prefix),
- i=i)
- i += 1
+ c_enum=c_enum_const(name, value, prefix))
ret += mcgen('''
} %(c_name)s;
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 18/50] qapi: change enum visitor to take QAPISchemaMember
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (16 preceding siblings ...)
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 17/50] qapi: do not define enumeration value explicitely Marc-André Lureau
@ 2017-09-11 11:05 ` Marc-André Lureau
2017-12-07 17:34 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 19/50] qapi: add 'if' to enum members Marc-André Lureau
` (33 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:05 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
This will allow to add and access more properties associated with enum
values/members, like the associated 'if' condition. We may want to
have a specialized type QAPISchemaEnumMember, for now this will do.
Suggested-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi.py | 40 +++++++++++++-------------
scripts/qapi-event.py | 2 +-
scripts/qapi-introspect.py | 5 ++--
scripts/qapi-types.py | 10 +++----
scripts/qapi-visit.py | 2 +-
scripts/qapi2texi.py | 2 +-
tests/qapi-schema/comments.out | 14 +++++++--
tests/qapi-schema/doc-good.out | 17 +++++++++--
tests/qapi-schema/empty.out | 9 +++++-
tests/qapi-schema/event-case.out | 9 +++++-
tests/qapi-schema/ident-with-escape.out | 9 +++++-
tests/qapi-schema/include-relpath.out | 14 +++++++--
tests/qapi-schema/include-repetition.out | 14 +++++++--
tests/qapi-schema/include-simple.out | 14 +++++++--
tests/qapi-schema/indented-expr.out | 9 +++++-
tests/qapi-schema/qapi-schema-test.out | 49 ++++++++++++++++++++++++++------
tests/qapi-schema/test-qapi.py | 17 +++++++----
17 files changed, 177 insertions(+), 59 deletions(-)
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 074ee221a1..386a577a59 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -1039,7 +1039,7 @@ class QAPISchemaVisitor(object):
def visit_builtin_type(self, name, info, json_type):
pass
- def visit_enum_type(self, name, info, ifcond, values, prefix):
+ def visit_enum_type(self, name, info, ifcond, members, prefix):
pass
def visit_array_type(self, name, info, ifcond, element_type):
@@ -1127,21 +1127,21 @@ class QAPISchemaBuiltinType(QAPISchemaType):
class QAPISchemaEnumType(QAPISchemaType):
- def __init__(self, name, info, doc, ifcond, values, prefix):
+ def __init__(self, name, info, doc, ifcond, members, prefix):
QAPISchemaType.__init__(self, name, info, doc, ifcond)
- for v in values:
- assert isinstance(v, QAPISchemaMember)
- v.set_owner(name)
+ for m in members:
+ assert isinstance(m, QAPISchemaMember)
+ m.set_owner(name)
assert prefix is None or isinstance(prefix, str)
- self.values = values
+ self.members = members
self.prefix = prefix
def check(self, schema):
seen = {}
- for v in self.values:
- v.check_clash(self.info, seen)
+ for m in self.members:
+ m.check_clash(self.info, seen)
if self.doc:
- self.doc.connect_member(v)
+ self.doc.connect_member(m)
def is_implicit(self):
# See QAPISchema._make_implicit_enum_type() and ._def_predefineds()
@@ -1151,14 +1151,14 @@ class QAPISchemaEnumType(QAPISchemaType):
return c_name(self.name)
def member_names(self):
- return [v.name for v in self.values]
+ return [m.name for m in self.members]
def json_type(self):
return 'string'
def visit(self, visitor):
visitor.visit_enum_type(self.name, self.info, self.ifcond,
- self.member_names(), self.prefix)
+ self.members, self.prefix)
class QAPISchemaArrayType(QAPISchemaType):
@@ -1952,19 +1952,19 @@ def ifcond_decorator(func):
return func_wrapper
-def gen_enum_lookup(name, values, prefix=None):
+def gen_enum_lookup(name, members, prefix=None):
ret = mcgen('''
const QEnumLookup %(c_name)s_lookup = {
.array = (const char *const[]) {
''',
c_name=c_name(name))
- for value in values:
- index = c_enum_const(name, value, prefix)
+ for m in members:
+ index = c_enum_const(name, m.name, prefix)
ret += mcgen('''
- [%(index)s] = "%(value)s",
+ [%(index)s] = "%(name)s",
''',
- index=index, value=value)
+ index=index, name=m.name)
ret += mcgen('''
},
@@ -1975,9 +1975,9 @@ const QEnumLookup %(c_name)s_lookup = {
return ret
-def gen_enum(name, values, prefix=None):
+def gen_enum(name, members, prefix=None):
# append automatically generated _MAX value
- enum_values = values + ['_MAX']
+ enum_members = members + [QAPISchemaMember('_MAX')]
ret = mcgen('''
@@ -1985,11 +1985,11 @@ typedef enum %(c_name)s {
''',
c_name=c_name(name))
- for value in enum_values:
+ for m in enum_members:
ret += mcgen('''
%(c_enum)s,
''',
- c_enum=c_enum_const(name, value, prefix))
+ c_enum=c_enum_const(name, m.name, prefix))
ret += mcgen('''
} %(c_name)s;
diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py
index bef301dfe9..38f4264817 100644
--- a/scripts/qapi-event.py
+++ b/scripts/qapi-event.py
@@ -168,7 +168,7 @@ class QAPISchemaGenEventVisitor(QAPISchemaVisitor):
def visit_event(self, name, info, ifcond, arg_type, boxed):
self.decl += gen_event_send_decl(name, arg_type, boxed)
self.defn += gen_event_send(name, arg_type, boxed)
- self._event_names.append(name)
+ self._event_names.append(QAPISchemaMember(name))
(input_file, output_dir, do_c, do_h, prefix, dummy) = parse_command_line()
diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
index 69d9afc792..32a58cf879 100644
--- a/scripts/qapi-introspect.py
+++ b/scripts/qapi-introspect.py
@@ -151,8 +151,9 @@ const QLitObject %(c_name)s = %(c_string)s;
def visit_builtin_type(self, name, info, json_type):
self._gen_qlit(name, 'builtin', {'json-type': json_type}, None)
- def visit_enum_type(self, name, info, ifcond, values, prefix):
- self._gen_qlit(name, 'enum', {'values': values}, ifcond)
+ def visit_enum_type(self, name, info, ifcond, members, prefix):
+ self._gen_qlit(name, 'enum',
+ {'values': [m.name for m in members]}, ifcond)
def visit_array_type(self, name, info, ifcond, element_type):
element = self._use_type(element_type)
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 789e89ff59..75c1823e44 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -203,16 +203,16 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
self.defn += gen_type_cleanup(name)
@ifcond_decorator
- def visit_enum_type(self, name, info, ifcond, values, prefix):
+ def visit_enum_type(self, name, info, ifcond, members, prefix):
# Special case for our lone builtin enum type
# TODO use something cleaner than existence of info
if not info:
- self._btin += gen_enum(name, values, prefix)
+ self._btin += gen_enum(name, members, prefix)
if do_builtins:
- self.defn += gen_enum_lookup(name, values, prefix)
+ self.defn += gen_enum_lookup(name, members, prefix)
else:
- self._fwdecl += gen_enum(name, values, prefix)
- self.defn += gen_enum_lookup(name, values, prefix)
+ self._fwdecl += gen_enum(name, members, prefix)
+ self.defn += gen_enum_lookup(name, members, prefix)
@ifcond_decorator
def visit_array_type(self, name, info, ifcond, element_type):
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 4b0e005437..7e816ae98e 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -284,7 +284,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
self._btin = None
@ifcond_decorator
- def visit_enum_type(self, name, info, ifcond, values, prefix):
+ def visit_enum_type(self, name, info, ifcond, members, prefix):
# Special case for our lone builtin enum type
# TODO use something cleaner than existence of info
if not info:
diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py
index cf63cb0006..e72e7cfe0b 100755
--- a/scripts/qapi2texi.py
+++ b/scripts/qapi2texi.py
@@ -207,7 +207,7 @@ class QAPISchemaGenDocVisitor(qapi.QAPISchemaVisitor):
def visit_begin(self, schema):
self.out = ''
- def visit_enum_type(self, name, info, ifcond, values, prefix):
+ def visit_enum_type(self, name, info, ifcond, members, prefix):
doc = self.cur_doc
if self.out:
self.out += '\n'
diff --git a/tests/qapi-schema/comments.out b/tests/qapi-schema/comments.out
index 17e652535c..17b493ec24 100644
--- a/tests/qapi-schema/comments.out
+++ b/tests/qapi-schema/comments.out
@@ -1,4 +1,14 @@
-enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
+enum QType
prefix QTYPE
-enum Status ['good', 'bad', 'ugly']
+ member none:
+ member qnull:
+ member qnum:
+ member qstring:
+ member qdict:
+ member qlist:
+ member qbool:
+enum Status
+ member good:
+ member bad:
+ member ugly:
object q_empty
diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out
index 63ca25a8b9..0de06ce345 100644
--- a/tests/qapi-schema/doc-good.out
+++ b/tests/qapi-schema/doc-good.out
@@ -1,19 +1,30 @@
object Base
member base1: Enum optional=False
-enum Enum ['one', 'two']
+enum Enum
+ member one:
+ member two:
object Object
base Base
tag base1
case one: Variant1
case two: Variant2
-enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
+enum QType
prefix QTYPE
+ member none:
+ member qnull:
+ member qnum:
+ member qstring:
+ member qdict:
+ member qlist:
+ member qbool:
object SugaredUnion
member type: SugaredUnionKind optional=False
tag type
case one: q_obj_Variant1-wrapper
case two: q_obj_Variant2-wrapper
-enum SugaredUnionKind ['one', 'two']
+enum SugaredUnionKind
+ member one:
+ member two:
object Variant1
member var1: str optional=False
object Variant2
diff --git a/tests/qapi-schema/empty.out b/tests/qapi-schema/empty.out
index 40b886ddae..9859251087 100644
--- a/tests/qapi-schema/empty.out
+++ b/tests/qapi-schema/empty.out
@@ -1,3 +1,10 @@
-enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
+enum QType
prefix QTYPE
+ member none:
+ member qnull:
+ member qnum:
+ member qstring:
+ member qdict:
+ member qlist:
+ member qbool:
object q_empty
diff --git a/tests/qapi-schema/event-case.out b/tests/qapi-schema/event-case.out
index 313c0fe7be..4dccc8f61e 100644
--- a/tests/qapi-schema/event-case.out
+++ b/tests/qapi-schema/event-case.out
@@ -1,5 +1,12 @@
-enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
+enum QType
prefix QTYPE
+ member none:
+ member qnull:
+ member qnum:
+ member qstring:
+ member qdict:
+ member qlist:
+ member qbool:
event oops None
boxed=False
object q_empty
diff --git a/tests/qapi-schema/ident-with-escape.out b/tests/qapi-schema/ident-with-escape.out
index b5637cb2e0..4d17bc6783 100644
--- a/tests/qapi-schema/ident-with-escape.out
+++ b/tests/qapi-schema/ident-with-escape.out
@@ -1,5 +1,12 @@
-enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
+enum QType
prefix QTYPE
+ member none:
+ member qnull:
+ member qnum:
+ member qstring:
+ member qdict:
+ member qlist:
+ member qbool:
command fooA q_obj_fooA-arg -> None
gen=True success_response=True boxed=False
object q_empty
diff --git a/tests/qapi-schema/include-relpath.out b/tests/qapi-schema/include-relpath.out
index 17e652535c..17b493ec24 100644
--- a/tests/qapi-schema/include-relpath.out
+++ b/tests/qapi-schema/include-relpath.out
@@ -1,4 +1,14 @@
-enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
+enum QType
prefix QTYPE
-enum Status ['good', 'bad', 'ugly']
+ member none:
+ member qnull:
+ member qnum:
+ member qstring:
+ member qdict:
+ member qlist:
+ member qbool:
+enum Status
+ member good:
+ member bad:
+ member ugly:
object q_empty
diff --git a/tests/qapi-schema/include-repetition.out b/tests/qapi-schema/include-repetition.out
index 17e652535c..17b493ec24 100644
--- a/tests/qapi-schema/include-repetition.out
+++ b/tests/qapi-schema/include-repetition.out
@@ -1,4 +1,14 @@
-enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
+enum QType
prefix QTYPE
-enum Status ['good', 'bad', 'ugly']
+ member none:
+ member qnull:
+ member qnum:
+ member qstring:
+ member qdict:
+ member qlist:
+ member qbool:
+enum Status
+ member good:
+ member bad:
+ member ugly:
object q_empty
diff --git a/tests/qapi-schema/include-simple.out b/tests/qapi-schema/include-simple.out
index 17e652535c..17b493ec24 100644
--- a/tests/qapi-schema/include-simple.out
+++ b/tests/qapi-schema/include-simple.out
@@ -1,4 +1,14 @@
-enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
+enum QType
prefix QTYPE
-enum Status ['good', 'bad', 'ugly']
+ member none:
+ member qnull:
+ member qnum:
+ member qstring:
+ member qdict:
+ member qlist:
+ member qbool:
+enum Status
+ member good:
+ member bad:
+ member ugly:
object q_empty
diff --git a/tests/qapi-schema/indented-expr.out b/tests/qapi-schema/indented-expr.out
index 586795f44d..8bdc016e55 100644
--- a/tests/qapi-schema/indented-expr.out
+++ b/tests/qapi-schema/indented-expr.out
@@ -1,5 +1,12 @@
-enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
+enum QType
prefix QTYPE
+ member none:
+ member qnull:
+ member qnum:
+ member qstring:
+ member qdict:
+ member qlist:
+ member qbool:
command eins None -> None
gen=True success_response=True boxed=False
object q_empty
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index fc5fd25f1b..9a7cafc269 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -33,7 +33,10 @@ event EVENT_F UserDefAlternate
object Empty1
object Empty2
base Empty1
-enum EnumOne ['value1', 'value2', 'value3']
+enum EnumOne
+ member value1:
+ member value2:
+ member value3:
object EventStructOne
member struct1: UserDefOne optional=False
member string: str optional=False
@@ -42,16 +45,25 @@ object ForceArrays
member unused1: UserDefOneList optional=False
member unused2: UserDefTwoList optional=False
member unused3: TestStructList optional=False
-enum MyEnum []
+enum MyEnum
object NestedEnumsOne
member enum1: EnumOne optional=False
member enum2: EnumOne optional=True
member enum3: EnumOne optional=False
member enum4: EnumOne optional=True
-enum QEnumTwo ['value1', 'value2']
+enum QEnumTwo
prefix QENUM_TWO
-enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
+ member value1:
+ member value2:
+enum QType
prefix QTYPE
+ member none:
+ member qnull:
+ member qnum:
+ member qstring:
+ member qdict:
+ member qlist:
+ member qbool:
alternate TestIfAlternate
tag type
case foo: int
@@ -60,7 +72,9 @@ alternate TestIfAlternate
command TestIfCmd q_obj_TestIfCmd-arg -> None
gen=True success_response=True boxed=False
if defined(TEST_IF_CMD) && defined(TEST_IF_STRUCT)
-enum TestIfEnum ['foo', 'bar']
+enum TestIfEnum
+ member foo:
+ member bar:
if defined(TEST_IF_ENUM)
event TestIfEvent q_obj_TestIfEvent-arg
boxed=False
@@ -73,7 +87,8 @@ object TestIfUnion
tag type
case foo: q_obj_TestStruct-wrapper
if defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)
-enum TestIfUnionKind ['foo']
+enum TestIfUnionKind
+ member foo:
if defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)
object TestStruct
member integer: int optional=False
@@ -122,7 +137,21 @@ object UserDefNativeListUnion
case string: q_obj_strList-wrapper
case sizes: q_obj_sizeList-wrapper
case any: q_obj_anyList-wrapper
-enum UserDefNativeListUnionKind ['integer', 's8', 's16', 's32', 's64', 'u8', 'u16', 'u32', 'u64', 'number', 'boolean', 'string', 'sizes', 'any']
+enum UserDefNativeListUnionKind
+ member integer:
+ member s8:
+ member s16:
+ member s32:
+ member s64:
+ member u8:
+ member u16:
+ member u32:
+ member u64:
+ member number:
+ member boolean:
+ member string:
+ member sizes:
+ member any:
object UserDefOne
base UserDefZero
member string: str optional=False
@@ -159,7 +188,8 @@ alternate __org.qemu_x-Alt
case b: __org.qemu_x-Base
object __org.qemu_x-Base
member __org.qemu_x-member1: __org.qemu_x-Enum optional=False
-enum __org.qemu_x-Enum ['__org.qemu_x-value']
+enum __org.qemu_x-Enum
+ member __org.qemu_x-value:
object __org.qemu_x-Struct
base __org.qemu_x-Base
member __org.qemu_x-member2: str optional=False
@@ -170,7 +200,8 @@ object __org.qemu_x-Union1
member type: __org.qemu_x-Union1Kind optional=False
tag type
case __org.qemu_x-branch: q_obj_str-wrapper
-enum __org.qemu_x-Union1Kind ['__org.qemu_x-branch']
+enum __org.qemu_x-Union1Kind
+ member __org.qemu_x-branch:
object __org.qemu_x-Union2
base __org.qemu_x-Base
tag __org.qemu_x-member1
diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
index 8627f978af..67c6c1ecef 100644
--- a/tests/qapi-schema/test-qapi.py
+++ b/tests/qapi-schema/test-qapi.py
@@ -17,19 +17,18 @@ import sys
class QAPISchemaTestVisitor(QAPISchemaVisitor):
- def visit_enum_type(self, name, info, ifcond, values, prefix):
- print 'enum %s %s' % (name, values)
+ def visit_enum_type(self, name, info, ifcond, members, prefix):
+ print 'enum %s' % name
if prefix:
print ' prefix %s' % prefix
+ self._print_members(members)
self._print_if(ifcond)
def visit_object_type(self, name, info, ifcond, base, members, variants):
print 'object %s' % name
if base:
print ' base %s' % base.name
- for m in members:
- print ' member %s: %s optional=%s' % \
- (m.name, m.type.name, m.optional)
+ self._print_members(members)
self._print_variants(variants)
self._print_if(ifcond)
@@ -51,6 +50,14 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
print ' boxed=%s' % boxed
self._print_if(ifcond)
+ @staticmethod
+ def _print_members(members):
+ for m in members:
+ print ' member %s:' % m.name,
+ if isinstance(m, QAPISchemaObjectTypeMember):
+ print '%s optional=%s' % (m.type.name, m.optional),
+ print
+
@staticmethod
def _print_variants(variants):
if variants:
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 19/50] qapi: add 'if' to enum members
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (17 preceding siblings ...)
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 18/50] qapi: change enum visitor to take QAPISchemaMember Marc-André Lureau
@ 2017-09-11 11:05 ` Marc-André Lureau
2017-12-08 8:38 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 20/50] qapi-event: add 'if' condition to generated enum Marc-André Lureau
` (32 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:05 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi.py | 39 ++++++++++++++++++++++++++++-----
tests/Makefile.include | 1 -
tests/qapi-schema/enum-dict-member.err | 1 -
tests/qapi-schema/enum-dict-member.exit | 1 -
tests/qapi-schema/enum-dict-member.json | 2 --
tests/qapi-schema/enum-dict-member.out | 0
tests/qapi-schema/qapi-schema-test.json | 5 +++--
tests/qapi-schema/qapi-schema-test.out | 3 ++-
tests/qapi-schema/test-qapi.py | 2 ++
9 files changed, 41 insertions(+), 13 deletions(-)
delete mode 100644 tests/qapi-schema/enum-dict-member.err
delete mode 100644 tests/qapi-schema/enum-dict-member.exit
delete mode 100644 tests/qapi-schema/enum-dict-member.json
delete mode 100644 tests/qapi-schema/enum-dict-member.out
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 386a577a59..1535de9ce7 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -659,6 +659,14 @@ def check_if(expr, info):
info, "'if' condition must be a string or a list of strings")
+def check_unknown_keys(info, dict, allowed_keys):
+ diff = set(dict) - allowed_keys
+ if not diff:
+ return
+ raise QAPISemError(info, "Dictionnary has unknown keys: %s (allowed: %s)" %
+ (', '.join(diff), ', '.join(allowed_keys)))
+
+
def check_type(info, source, value, allow_array=False,
allow_dict=False, allow_optional=False,
allow_metas=[]):
@@ -739,6 +747,10 @@ def check_event(expr, info):
allow_metas=meta)
+def enum_get_values(expr):
+ return [e if isinstance(e, str) else e['name'] for e in expr['data']]
+
+
def check_union(expr, info):
name = expr['union']
base = expr.get('base')
@@ -798,7 +810,7 @@ def check_union(expr, info):
# If the discriminator names an enum type, then all members
# of 'data' must also be members of the enum type.
if enum_define:
- if key not in enum_define['data']:
+ if key not in enum_get_values(enum_define):
raise QAPISemError(info,
"Discriminator value '%s' is not found in "
"enum '%s'"
@@ -806,7 +818,7 @@ def check_union(expr, info):
# If discriminator is user-defined, ensure all values are covered
if enum_define:
- for value in enum_define['data']:
+ for value in enum_get_values(enum_define):
if value not in members.keys():
raise QAPISemError(info, "Union '%s' data missing '%s' branch"
% (name, value))
@@ -837,7 +849,7 @@ def check_alternate(expr, info):
if qtype == 'QTYPE_QSTRING':
enum_expr = enum_types.get(value)
if enum_expr:
- for v in enum_expr['data']:
+ for v in enum_get_values(enum_expr):
if v in ['on', 'off']:
conflicting.add('QTYPE_QBOOL')
if re.match(r'[-+0-9.]', v): # lazy, could be tightened
@@ -865,6 +877,14 @@ def check_enum(expr, info):
raise QAPISemError(info,
"Enum '%s' requires a string for 'prefix'" % name)
for member in members:
+ if isinstance(member, dict):
+ if 'name' not in member:
+ raise QAPISemError(info, "Dictionary member of enum '%s' must "
+ "have a 'name' key" % name)
+ if 'if' in member:
+ check_if(member, info)
+ check_unknown_keys(info, member, {'name', 'if'})
+ member = member['name']
check_name(info, "Member of enum '%s'" % name, member,
enum_member=True)
@@ -1280,9 +1300,11 @@ class QAPISchemaObjectType(QAPISchemaType):
class QAPISchemaMember(object):
role = 'member'
- def __init__(self, name):
+ def __init__(self, name, ifcond=None):
assert isinstance(name, str)
+ assert ifcond is None or isinstance(ifcond, str)
self.name = name
+ self.ifcond = ifcond
self.owner = None
def set_owner(self, name):
@@ -1559,7 +1581,14 @@ class QAPISchema(object):
qtype_values, 'QTYPE'))
def _make_enum_members(self, values):
- return [QAPISchemaMember(v) for v in values]
+ enum = []
+ for v in values:
+ ifcond = None
+ if isinstance(v, dict):
+ ifcond = v.get('if')
+ v = v['name']
+ enum.append(QAPISchemaMember(v, ifcond))
+ return enum
def _make_implicit_enum_type(self, name, info, ifcond, values):
# See also QAPISchemaObjectTypeMember._pretty_owner()
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 8dac7c9083..a9f0ddbe01 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -443,7 +443,6 @@ qapi-schema += empty.json
qapi-schema += enum-bad-name.json
qapi-schema += enum-bad-prefix.json
qapi-schema += enum-clash-member.json
-qapi-schema += enum-dict-member.json
qapi-schema += enum-int-member.json
qapi-schema += enum-member-case.json
qapi-schema += enum-missing-data.json
diff --git a/tests/qapi-schema/enum-dict-member.err b/tests/qapi-schema/enum-dict-member.err
deleted file mode 100644
index 8ca146ea59..0000000000
--- a/tests/qapi-schema/enum-dict-member.err
+++ /dev/null
@@ -1 +0,0 @@
-tests/qapi-schema/enum-dict-member.json:2: Member of enum 'MyEnum' requires a string name
diff --git a/tests/qapi-schema/enum-dict-member.exit b/tests/qapi-schema/enum-dict-member.exit
deleted file mode 100644
index d00491fd7e..0000000000
--- a/tests/qapi-schema/enum-dict-member.exit
+++ /dev/null
@@ -1 +0,0 @@
-1
diff --git a/tests/qapi-schema/enum-dict-member.json b/tests/qapi-schema/enum-dict-member.json
deleted file mode 100644
index 79672e0f09..0000000000
--- a/tests/qapi-schema/enum-dict-member.json
+++ /dev/null
@@ -1,2 +0,0 @@
-# we reject any enum member that is not a string
-{ 'enum': 'MyEnum', 'data': [ { 'value': 'str' } ] }
diff --git a/tests/qapi-schema/enum-dict-member.out b/tests/qapi-schema/enum-dict-member.out
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index dc2c444fc1..ad2b405d83 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -194,7 +194,8 @@
{ 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
'if': 'defined(TEST_IF_STRUCT)' }
-{ 'enum': 'TestIfEnum', 'data': [ 'foo', 'bar' ],
+{ 'enum': 'TestIfEnum', 'data':
+ [ 'foo', { 'name' : 'bar', 'if': 'defined(TEST_IF_ENUM_BAR)' } ],
'if': 'defined(TEST_IF_ENUM)' }
{ 'union': 'TestIfUnion', 'data': { 'foo': 'TestStruct' },
@@ -203,7 +204,7 @@
{ 'alternate': 'TestIfAlternate', 'data': { 'foo': 'int', 'bar': 'TestStruct' },
'if': 'defined(TEST_IF_ALT) && defined(TEST_IF_STRUCT)' }
-{ 'command': 'TestIfCmd', 'data': { 'foo': 'TestIfStruct' },
+{ 'command': 'TestIfCmd', 'data': { 'foo': 'TestIfStruct', 'bar': 'TestIfEnum' },
'if': 'defined(TEST_IF_CMD) && defined(TEST_IF_STRUCT)' }
{ 'event': 'TestIfEvent', 'data': { 'foo': 'TestIfStruct' },
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index 9a7cafc269..8a0cf1a551 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -74,7 +74,7 @@ command TestIfCmd q_obj_TestIfCmd-arg -> None
if defined(TEST_IF_CMD) && defined(TEST_IF_STRUCT)
enum TestIfEnum
member foo:
- member bar:
+ member bar: if=defined(TEST_IF_ENUM_BAR)
if defined(TEST_IF_ENUM)
event TestIfEvent q_obj_TestIfEvent-arg
boxed=False
@@ -228,6 +228,7 @@ object q_obj_EVENT_D-arg
member enum3: EnumOne optional=True
object q_obj_TestIfCmd-arg
member foo: TestIfStruct optional=False
+ member bar: TestIfEnum optional=False
if defined(TEST_IF_CMD) && defined(TEST_IF_STRUCT)
object q_obj_TestIfEvent-arg
member foo: TestIfStruct optional=False
diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
index 67c6c1ecef..a86c3b5ee1 100644
--- a/tests/qapi-schema/test-qapi.py
+++ b/tests/qapi-schema/test-qapi.py
@@ -56,6 +56,8 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
print ' member %s:' % m.name,
if isinstance(m, QAPISchemaObjectTypeMember):
print '%s optional=%s' % (m.type.name, m.optional),
+ if m.ifcond:
+ print 'if=%s' % m.ifcond,
print
@staticmethod
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 20/50] qapi-event: add 'if' condition to generated enum
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (18 preceding siblings ...)
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 19/50] qapi: add 'if' to enum members Marc-André Lureau
@ 2017-09-11 11:05 ` Marc-André Lureau
2017-12-08 13:58 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 21/50] qapi: add #if conditions on generated enum members Marc-André Lureau
` (31 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:05 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
Add condition to QAPIEvent enum members based on the event 'if'.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi-event.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py
index 38f4264817..60c6f7030d 100644
--- a/scripts/qapi-event.py
+++ b/scripts/qapi-event.py
@@ -168,7 +168,7 @@ class QAPISchemaGenEventVisitor(QAPISchemaVisitor):
def visit_event(self, name, info, ifcond, arg_type, boxed):
self.decl += gen_event_send_decl(name, arg_type, boxed)
self.defn += gen_event_send(name, arg_type, boxed)
- self._event_names.append(QAPISchemaMember(name))
+ self._event_names.append(QAPISchemaMember(name, ifcond))
(input_file, output_dir, do_c, do_h, prefix, dummy) = parse_command_line()
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 21/50] qapi: add #if conditions on generated enum members
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (19 preceding siblings ...)
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 20/50] qapi-event: add 'if' condition to generated enum Marc-André Lureau
@ 2017-09-11 11:05 ` Marc-André Lureau
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 22/50] tests: add some enum members tests Marc-André Lureau
` (30 subsequent siblings)
51 siblings, 0 replies; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:05 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi.py | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 1535de9ce7..df2a304e8f 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -1989,11 +1989,13 @@ const QEnumLookup %(c_name)s_lookup = {
''',
c_name=c_name(name))
for m in members:
+ ret += gen_if(m.ifcond)
index = c_enum_const(name, m.name, prefix)
ret += mcgen('''
[%(index)s] = "%(name)s",
''',
index=index, name=m.name)
+ ret += gen_endif(m.ifcond)
ret += mcgen('''
},
@@ -2015,10 +2017,12 @@ typedef enum %(c_name)s {
c_name=c_name(name))
for m in enum_members:
+ ret += gen_if(m.ifcond)
ret += mcgen('''
%(c_enum)s,
''',
c_enum=c_enum_const(name, m.name, prefix))
+ ret += gen_endif(m.ifcond)
ret += mcgen('''
} %(c_name)s;
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 22/50] tests: add some enum members tests
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (20 preceding siblings ...)
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 21/50] qapi: add #if conditions on generated enum members Marc-André Lureau
@ 2017-09-11 11:05 ` Marc-André Lureau
2017-12-08 17:58 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 23/50] qapi: add 'if' to struct members and implicit objects members Marc-André Lureau
` (29 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:05 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
tests/Makefile.include | 3 +++
tests/qapi-schema/enum-dict-member-invalid.err | 1 +
tests/qapi-schema/enum-dict-member-invalid.exit | 1 +
tests/qapi-schema/enum-dict-member-invalid.json | 2 ++
tests/qapi-schema/enum-dict-member-invalid.out | 0
tests/qapi-schema/enum-dict-member-invalid2.err | 1 +
tests/qapi-schema/enum-dict-member-invalid2.exit | 1 +
tests/qapi-schema/enum-dict-member-invalid2.json | 2 ++
tests/qapi-schema/enum-dict-member-invalid2.out | 0
tests/qapi-schema/enum-if-invalid.err | 1 +
tests/qapi-schema/enum-if-invalid.exit | 1 +
tests/qapi-schema/enum-if-invalid.json | 3 +++
tests/qapi-schema/enum-if-invalid.out | 0
13 files changed, 16 insertions(+)
create mode 100644 tests/qapi-schema/enum-dict-member-invalid.err
create mode 100644 tests/qapi-schema/enum-dict-member-invalid.exit
create mode 100644 tests/qapi-schema/enum-dict-member-invalid.json
create mode 100644 tests/qapi-schema/enum-dict-member-invalid.out
create mode 100644 tests/qapi-schema/enum-dict-member-invalid2.err
create mode 100644 tests/qapi-schema/enum-dict-member-invalid2.exit
create mode 100644 tests/qapi-schema/enum-dict-member-invalid2.json
create mode 100644 tests/qapi-schema/enum-dict-member-invalid2.out
create mode 100644 tests/qapi-schema/enum-if-invalid.err
create mode 100644 tests/qapi-schema/enum-if-invalid.exit
create mode 100644 tests/qapi-schema/enum-if-invalid.json
create mode 100644 tests/qapi-schema/enum-if-invalid.out
diff --git a/tests/Makefile.include b/tests/Makefile.include
index a9f0ddbe01..0aa532f029 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -443,6 +443,9 @@ qapi-schema += empty.json
qapi-schema += enum-bad-name.json
qapi-schema += enum-bad-prefix.json
qapi-schema += enum-clash-member.json
+qapi-schema += enum-dict-member-invalid.json
+qapi-schema += enum-dict-member-invalid2.json
+qapi-schema += enum-if-invalid.json
qapi-schema += enum-int-member.json
qapi-schema += enum-member-case.json
qapi-schema += enum-missing-data.json
diff --git a/tests/qapi-schema/enum-dict-member-invalid.err b/tests/qapi-schema/enum-dict-member-invalid.err
new file mode 100644
index 0000000000..d12cca0df3
--- /dev/null
+++ b/tests/qapi-schema/enum-dict-member-invalid.err
@@ -0,0 +1 @@
+tests/qapi-schema/enum-dict-member-invalid.json:2: Dictionary member of enum 'MyEnum' must have a 'name' key
diff --git a/tests/qapi-schema/enum-dict-member-invalid.exit b/tests/qapi-schema/enum-dict-member-invalid.exit
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/tests/qapi-schema/enum-dict-member-invalid.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/enum-dict-member-invalid.json b/tests/qapi-schema/enum-dict-member-invalid.json
new file mode 100644
index 0000000000..9cf8406867
--- /dev/null
+++ b/tests/qapi-schema/enum-dict-member-invalid.json
@@ -0,0 +1,2 @@
+# we reject any enum member that is not a string or a dict with 'name'
+{ 'enum': 'MyEnum', 'data': [ { 'value': 'str' } ] }
diff --git a/tests/qapi-schema/enum-dict-member-invalid.out b/tests/qapi-schema/enum-dict-member-invalid.out
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/qapi-schema/enum-dict-member-invalid2.err b/tests/qapi-schema/enum-dict-member-invalid2.err
new file mode 100644
index 0000000000..f7dc1a2b33
--- /dev/null
+++ b/tests/qapi-schema/enum-dict-member-invalid2.err
@@ -0,0 +1 @@
+tests/qapi-schema/enum-dict-member-invalid2.json:2: Dictionnary has unknown keys: bad-key (allowed: name, if)
diff --git a/tests/qapi-schema/enum-dict-member-invalid2.exit b/tests/qapi-schema/enum-dict-member-invalid2.exit
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/tests/qapi-schema/enum-dict-member-invalid2.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/enum-dict-member-invalid2.json b/tests/qapi-schema/enum-dict-member-invalid2.json
new file mode 100644
index 0000000000..6664c59201
--- /dev/null
+++ b/tests/qapi-schema/enum-dict-member-invalid2.json
@@ -0,0 +1,2 @@
+# we reject any enum member that is not a string or a dict with 'name'
+{ 'enum': 'MyEnum', 'data': [ { 'name': 'foo', 'bad-key': 'str' } ] }
diff --git a/tests/qapi-schema/enum-dict-member-invalid2.out b/tests/qapi-schema/enum-dict-member-invalid2.out
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/qapi-schema/enum-if-invalid.err b/tests/qapi-schema/enum-if-invalid.err
new file mode 100644
index 0000000000..54c3cf887b
--- /dev/null
+++ b/tests/qapi-schema/enum-if-invalid.err
@@ -0,0 +1 @@
+tests/qapi-schema/enum-if-invalid.json:2: 'if' condition must be a string or a list of strings
diff --git a/tests/qapi-schema/enum-if-invalid.exit b/tests/qapi-schema/enum-if-invalid.exit
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/tests/qapi-schema/enum-if-invalid.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/enum-if-invalid.json b/tests/qapi-schema/enum-if-invalid.json
new file mode 100644
index 0000000000..60bd0ef1d7
--- /dev/null
+++ b/tests/qapi-schema/enum-if-invalid.json
@@ -0,0 +1,3 @@
+# check invalid 'if' type
+{ 'enum': 'TestIfEnum', 'data':
+ [ 'foo', { 'name' : 'bar', 'if': { 'val': 'foo' } } ] }
diff --git a/tests/qapi-schema/enum-if-invalid.out b/tests/qapi-schema/enum-if-invalid.out
new file mode 100644
index 0000000000..e69de29bb2
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 23/50] qapi: add 'if' to struct members and implicit objects members
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (21 preceding siblings ...)
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 22/50] tests: add some enum members tests Marc-André Lureau
@ 2017-09-11 11:05 ` Marc-André Lureau
2017-12-09 8:18 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 24/50] qapi: add some struct member tests Marc-André Lureau
` (28 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:05 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
check_type() will now accept a DICT { 'type': TYPENAME, 'if': ... }
instead of a TYPENAME. This is the case in various situations where
implicit object types are allowed such as commands/events arguments
and return type, base and branches of union & alternate.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi.py | 20 ++++++++++++++++----
tests/qapi-schema/qapi-schema-test.json | 12 +++++++++---
tests/qapi-schema/qapi-schema-test.out | 4 +++-
3 files changed, 28 insertions(+), 8 deletions(-)
diff --git a/scripts/qapi.py b/scripts/qapi.py
index df2a304e8f..15711f96fa 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -696,7 +696,15 @@ def check_type(info, source, value, allow_array=False,
return
if not allow_dict:
- raise QAPISemError(info, "%s should be a type name" % source)
+ if isinstance(value, dict) and 'type' in value:
+ check_type(info, source, value['type'], allow_array,
+ allow_dict, allow_optional, allow_metas)
+ if 'if' in value:
+ check_if(value, info)
+ check_unknown_keys(info, value, {'type', 'if'})
+ return
+ else:
+ raise QAPISemError(info, "%s should be a type name" % source)
if not isinstance(value, OrderedDict):
raise QAPISemError(info,
@@ -1345,8 +1353,8 @@ class QAPISchemaMember(object):
class QAPISchemaObjectTypeMember(QAPISchemaMember):
- def __init__(self, name, typ, optional):
- QAPISchemaMember.__init__(self, name)
+ def __init__(self, name, typ, optional, ifcond=None):
+ QAPISchemaMember.__init__(self, name, ifcond)
assert isinstance(typ, str)
assert isinstance(optional, bool)
self._type_name = typ
@@ -1637,13 +1645,17 @@ class QAPISchema(object):
def _make_member(self, name, typ, info):
optional = False
+ ifcond = None
if name.startswith('*'):
name = name[1:]
optional = True
+ if isinstance(typ, dict):
+ ifcond = typ.get('if')
+ typ = typ['type']
if isinstance(typ, list):
assert len(typ) == 1
typ = self._make_array_type(typ[0], info)
- return QAPISchemaObjectTypeMember(name, typ, optional)
+ return QAPISchemaObjectTypeMember(name, typ, optional, ifcond)
def _make_members(self, data, info):
return [self._make_member(key, value, info)
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index ad2b405d83..5cfccabb3d 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -191,7 +191,9 @@
# test 'if' condition handling
-{ 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
+{ 'struct': 'TestIfStruct', 'data':
+ { 'foo': 'int',
+ 'bar': { 'type': 'int', 'if': 'defined(TEST_IF_STRUCT_BAR)'} },
'if': 'defined(TEST_IF_STRUCT)' }
{ 'enum': 'TestIfEnum', 'data':
@@ -204,8 +206,12 @@
{ 'alternate': 'TestIfAlternate', 'data': { 'foo': 'int', 'bar': 'TestStruct' },
'if': 'defined(TEST_IF_ALT) && defined(TEST_IF_STRUCT)' }
-{ 'command': 'TestIfCmd', 'data': { 'foo': 'TestIfStruct', 'bar': 'TestIfEnum' },
+{ 'command': 'TestIfCmd', 'data':
+ { 'foo': 'TestIfStruct',
+ 'bar': { 'type': 'TestIfEnum', 'if': 'defined(TEST_IF_CMD_BAR)' } },
'if': 'defined(TEST_IF_CMD) && defined(TEST_IF_STRUCT)' }
-{ 'event': 'TestIfEvent', 'data': { 'foo': 'TestIfStruct' },
+{ 'event': 'TestIfEvent', 'data':
+ { 'foo': 'TestIfStruct',
+ 'bar': { 'type': 'TestIfEnum', 'if': 'defined(TEST_IF_EVT_BAR)' } },
'if': 'defined(TEST_IF_EVT) && defined(TEST_IF_STRUCT)' }
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index 8a0cf1a551..6df4e49c69 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -81,6 +81,7 @@ event TestIfEvent q_obj_TestIfEvent-arg
if defined(TEST_IF_EVT) && defined(TEST_IF_STRUCT)
object TestIfStruct
member foo: int optional=False
+ member bar: int optional=False if=defined(TEST_IF_STRUCT_BAR)
if defined(TEST_IF_STRUCT)
object TestIfUnion
member type: TestIfUnionKind optional=False
@@ -228,10 +229,11 @@ object q_obj_EVENT_D-arg
member enum3: EnumOne optional=True
object q_obj_TestIfCmd-arg
member foo: TestIfStruct optional=False
- member bar: TestIfEnum optional=False
+ member bar: TestIfEnum optional=False if=defined(TEST_IF_CMD_BAR)
if defined(TEST_IF_CMD) && defined(TEST_IF_STRUCT)
object q_obj_TestIfEvent-arg
member foo: TestIfStruct optional=False
+ member bar: TestIfEnum optional=False if=defined(TEST_IF_EVT_BAR)
if defined(TEST_IF_EVT) && defined(TEST_IF_STRUCT)
object q_obj_TestStruct-wrapper
member data: TestStruct optional=False
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 24/50] qapi: add some struct member tests
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (22 preceding siblings ...)
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 23/50] qapi: add 'if' to struct members and implicit objects members Marc-André Lureau
@ 2017-09-11 11:05 ` Marc-André Lureau
2017-12-09 9:07 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 25/50] qapi: add #if conditions to generated struct members Marc-André Lureau
` (27 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:05 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
tests/Makefile.include | 2 ++
tests/qapi-schema/struct-if-invalid.err | 1 +
tests/qapi-schema/struct-if-invalid.exit | 1 +
tests/qapi-schema/struct-if-invalid.json | 3 +++
tests/qapi-schema/struct-if-invalid.out | 0
tests/qapi-schema/struct-member-type.err | 0
tests/qapi-schema/struct-member-type.exit | 1 +
tests/qapi-schema/struct-member-type.json | 2 ++
tests/qapi-schema/struct-member-type.out | 12 ++++++++++++
9 files changed, 22 insertions(+)
create mode 100644 tests/qapi-schema/struct-if-invalid.err
create mode 100644 tests/qapi-schema/struct-if-invalid.exit
create mode 100644 tests/qapi-schema/struct-if-invalid.json
create mode 100644 tests/qapi-schema/struct-if-invalid.out
create mode 100644 tests/qapi-schema/struct-member-type.err
create mode 100644 tests/qapi-schema/struct-member-type.exit
create mode 100644 tests/qapi-schema/struct-member-type.json
create mode 100644 tests/qapi-schema/struct-member-type.out
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 0aa532f029..44a3d8895e 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -520,7 +520,9 @@ qapi-schema += returns-whitelist.json
qapi-schema += struct-base-clash-deep.json
qapi-schema += struct-base-clash.json
qapi-schema += struct-data-invalid.json
+qapi-schema += struct-if-invalid.json
qapi-schema += struct-member-invalid.json
+qapi-schema += struct-member-type.json
qapi-schema += trailing-comma-list.json
qapi-schema += trailing-comma-object.json
qapi-schema += type-bypass-bad-gen.json
diff --git a/tests/qapi-schema/struct-if-invalid.err b/tests/qapi-schema/struct-if-invalid.err
new file mode 100644
index 0000000000..42245262a9
--- /dev/null
+++ b/tests/qapi-schema/struct-if-invalid.err
@@ -0,0 +1 @@
+tests/qapi-schema/struct-if-invalid.json:2: Member 'bar' of 'data' for struct 'TestIfStruct' should be a type name
diff --git a/tests/qapi-schema/struct-if-invalid.exit b/tests/qapi-schema/struct-if-invalid.exit
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/tests/qapi-schema/struct-if-invalid.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/struct-if-invalid.json b/tests/qapi-schema/struct-if-invalid.json
new file mode 100644
index 0000000000..466cdb61e1
--- /dev/null
+++ b/tests/qapi-schema/struct-if-invalid.json
@@ -0,0 +1,3 @@
+# check missing 'type'
+{ 'struct': 'TestIfStruct', 'data':
+ { 'foo': 'int', 'bar': { 'if': 'defined(TEST_IF_STRUCT_BAR)' } } }
diff --git a/tests/qapi-schema/struct-if-invalid.out b/tests/qapi-schema/struct-if-invalid.out
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/qapi-schema/struct-member-type.err b/tests/qapi-schema/struct-member-type.err
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/qapi-schema/struct-member-type.exit b/tests/qapi-schema/struct-member-type.exit
new file mode 100644
index 0000000000..573541ac97
--- /dev/null
+++ b/tests/qapi-schema/struct-member-type.exit
@@ -0,0 +1 @@
+0
diff --git a/tests/qapi-schema/struct-member-type.json b/tests/qapi-schema/struct-member-type.json
new file mode 100644
index 0000000000..8b33027817
--- /dev/null
+++ b/tests/qapi-schema/struct-member-type.json
@@ -0,0 +1,2 @@
+# check member 'a' with 'type' key only
+{ 'struct': 'foo', 'data': { 'a': { 'type': 'str' } } }
diff --git a/tests/qapi-schema/struct-member-type.out b/tests/qapi-schema/struct-member-type.out
new file mode 100644
index 0000000000..04b969d2e3
--- /dev/null
+++ b/tests/qapi-schema/struct-member-type.out
@@ -0,0 +1,12 @@
+enum QType
+ prefix QTYPE
+ member none:
+ member qnull:
+ member qnum:
+ member qstring:
+ member qdict:
+ member qlist:
+ member qbool:
+object foo
+ member a: str optional=False
+object q_empty
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 25/50] qapi: add #if conditions to generated struct members
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (23 preceding siblings ...)
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 24/50] qapi: add some struct member tests Marc-André Lureau
@ 2017-09-11 11:05 ` Marc-André Lureau
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 26/50] qapi: add 'if' on union variants Marc-André Lureau
` (26 subsequent siblings)
51 siblings, 0 replies; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:05 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi-introspect.py | 2 ++
scripts/qapi-types.py | 2 ++
scripts/qapi-visit.py | 2 ++
3 files changed, 6 insertions(+)
diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
index 32a58cf879..0e43e470bb 100644
--- a/scripts/qapi-introspect.py
+++ b/scripts/qapi-introspect.py
@@ -139,6 +139,8 @@ const QLitObject %(c_name)s = %(c_string)s;
ret = {'name': member.name, 'type': self._use_type(member.type)}
if member.optional:
ret['default'] = None
+ if member.ifcond:
+ ret = (ret, member.ifcond)
return ret
def _gen_variants(self, tag_name, variants):
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 75c1823e44..7e6df21f53 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -41,6 +41,7 @@ struct %(c_name)s {
def gen_struct_members(members):
ret = ''
for memb in members:
+ ret += gen_if(memb.ifcond)
if memb.optional:
ret += mcgen('''
bool has_%(c_name)s;
@@ -50,6 +51,7 @@ def gen_struct_members(members):
%(c_type)s %(c_name)s;
''',
c_type=memb.type.c_type(), c_name=c_name(memb.name))
+ ret += gen_endif(memb.ifcond)
return ret
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 7e816ae98e..6a3a52e39d 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -53,6 +53,7 @@ void visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp)
c_type=base.c_name())
for memb in members:
+ ret += gen_if(memb.ifcond)
if memb.optional:
ret += mcgen('''
if (visit_optional(v, "%(name)s", &obj->has_%(c_name)s)) {
@@ -72,6 +73,7 @@ void visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp)
ret += mcgen('''
}
''')
+ ret += gen_endif(memb.ifcond)
if variants:
ret += mcgen('''
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 26/50] qapi: add 'if' on union variants
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (24 preceding siblings ...)
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 25/50] qapi: add #if conditions to generated struct members Marc-André Lureau
@ 2017-09-11 11:05 ` Marc-André Lureau
2017-12-11 10:36 ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 27/50] qapi: add #if conditions to generated variants Marc-André Lureau
` (25 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:05 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi.py | 15 ++++++++++-----
tests/qapi-schema/qapi-schema-test.json | 7 ++++++-
tests/qapi-schema/qapi-schema-test.out | 8 ++++++++
tests/qapi-schema/test-qapi.py | 5 ++++-
4 files changed, 28 insertions(+), 7 deletions(-)
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 15711f96fa..2f14edfa1f 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -1412,8 +1412,8 @@ class QAPISchemaObjectTypeVariants(object):
class QAPISchemaObjectTypeVariant(QAPISchemaObjectTypeMember):
role = 'branch'
- def __init__(self, name, typ):
- QAPISchemaObjectTypeMember.__init__(self, name, typ, False)
+ def __init__(self, name, typ, ifcond=None):
+ QAPISchemaObjectTypeMember.__init__(self, name, typ, False, ifcond)
class QAPISchemaAlternateType(QAPISchemaType):
@@ -1674,13 +1674,18 @@ class QAPISchema(object):
return QAPISchemaObjectTypeVariant(case, typ)
def _make_simple_variant(self, case, typ, info):
+ ifcond = None
+ if isinstance(typ, dict):
+ check_unknown_keys(info, typ, {'type', 'if'})
+ ifcond = typ.get('if')
+ typ = typ['type']
if isinstance(typ, list):
assert len(typ) == 1
typ = self._make_array_type(typ[0], info)
typ = self._make_implicit_object_type(
typ, info, None, self.lookup_type(typ).ifcond,
'wrapper', [self._make_member('data', typ, info)])
- return QAPISchemaObjectTypeVariant(case, typ)
+ return QAPISchemaObjectTypeVariant(case, typ, ifcond)
def _def_union_type(self, expr, info, doc):
name = expr['union']
@@ -1700,8 +1705,8 @@ class QAPISchema(object):
else:
variants = [self._make_simple_variant(key, value, info)
for (key, value) in data.iteritems()]
- typ = self._make_implicit_enum_type(name, info, ifcond,
- [v.name for v in variants])
+ values = [{'name': v.name, 'if': v.ifcond} for v in variants]
+ typ = self._make_implicit_enum_type(name, info, ifcond, values)
tag_member = QAPISchemaObjectTypeMember('type', typ, False)
members = [tag_member]
self._def_entity(
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index 5cfccabb3d..895e80a978 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -200,9 +200,14 @@
[ 'foo', { 'name' : 'bar', 'if': 'defined(TEST_IF_ENUM_BAR)' } ],
'if': 'defined(TEST_IF_ENUM)' }
-{ 'union': 'TestIfUnion', 'data': { 'foo': 'TestStruct' },
+{ 'union': 'TestIfUnion', 'data':
+ { 'foo': 'TestStruct',
+ 'union_bar': { 'type': 'str', 'if': 'defined(TEST_IF_UNION_BAR)'} },
'if': 'defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)' }
+{ 'command': 'TestIfUnionCmd', 'data': { 'union_cmd_arg': 'TestIfUnion' },
+ 'if': 'defined(TEST_IF_UNION)' }
+
{ 'alternate': 'TestIfAlternate', 'data': { 'foo': 'int', 'bar': 'TestStruct' },
'if': 'defined(TEST_IF_ALT) && defined(TEST_IF_STRUCT)' }
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index 6df4e49c69..ee009c5626 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -87,9 +87,14 @@ object TestIfUnion
member type: TestIfUnionKind optional=False
tag type
case foo: q_obj_TestStruct-wrapper
+ case union_bar: q_obj_str-wrapper if=defined(TEST_IF_UNION_BAR)
if defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)
+command TestIfUnionCmd q_obj_TestIfUnionCmd-arg -> None
+ gen=True success_response=True boxed=False
+ if defined(TEST_IF_UNION)
enum TestIfUnionKind
member foo:
+ member union_bar: if=defined(TEST_IF_UNION_BAR)
if defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)
object TestStruct
member integer: int optional=False
@@ -235,6 +240,9 @@ object q_obj_TestIfEvent-arg
member foo: TestIfStruct optional=False
member bar: TestIfEnum optional=False if=defined(TEST_IF_EVT_BAR)
if defined(TEST_IF_EVT) && defined(TEST_IF_STRUCT)
+object q_obj_TestIfUnionCmd-arg
+ member union_cmd_arg: TestIfUnion optional=False
+ if defined(TEST_IF_UNION)
object q_obj_TestStruct-wrapper
member data: TestStruct optional=False
object q_obj_UserDefFlatUnion2-base
diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
index a86c3b5ee1..87a8efff78 100644
--- a/tests/qapi-schema/test-qapi.py
+++ b/tests/qapi-schema/test-qapi.py
@@ -65,7 +65,10 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
if variants:
print ' tag %s' % variants.tag_member.name
for v in variants.variants:
- print ' case %s: %s' % (v.name, v.type.name)
+ print ' case %s: %s' % (v.name, v.type.name),
+ if v.ifcond:
+ print 'if=%s' % v.ifcond,
+ print
@staticmethod
def _print_if(ifcond):
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 27/50] qapi: add #if conditions to generated variants
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (25 preceding siblings ...)
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 26/50] qapi: add 'if' on union variants Marc-André Lureau
@ 2017-09-11 11:06 ` Marc-André Lureau
2017-12-13 12:37 ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 28/50] qapi: add 'if' to alternate variant Marc-André Lureau
` (24 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:06 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi-introspect.py | 3 ++-
scripts/qapi-types.py | 2 ++
scripts/qapi-visit.py | 4 ++++
3 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
index 0e43e470bb..ef2d5577db 100644
--- a/scripts/qapi-introspect.py
+++ b/scripts/qapi-introspect.py
@@ -148,7 +148,8 @@ const QLitObject %(c_name)s = %(c_string)s;
'variants': [self._gen_variant(v) for v in variants]}
def _gen_variant(self, variant):
- return {'case': variant.name, 'type': self._use_type(variant.type)}
+ return ({'case': variant.name, 'type': self._use_type(variant.type)},
+ variant.ifcond)
def visit_builtin_type(self, name, info, json_type):
self._gen_qlit(name, 'builtin', {'json-type': json_type}, None)
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 7e6df21f53..312685c295 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -131,11 +131,13 @@ def gen_variants(variants):
c_name=c_name(variants.tag_member.name))
for var in variants.variants:
+ ret += gen_if(var.ifcond)
ret += mcgen('''
%(c_type)s %(c_name)s;
''',
c_type=var.type.c_unboxed_type(),
c_name=c_name(var.name))
+ ret += gen_endif(var.ifcond)
ret += mcgen('''
} u;
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 6a3a52e39d..369e1f927d 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -82,6 +82,7 @@ void visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp)
c_name=c_name(variants.tag_member.name))
for var in variants.variants:
+ ret += gen_if(var.ifcond)
ret += mcgen('''
case %(case)s:
visit_type_%(c_type)s_members(v, &obj->u.%(c_name)s, &err);
@@ -92,6 +93,7 @@ void visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp)
variants.tag_member.type.prefix),
c_type=var.type.c_name(), c_name=c_name(var.name))
+ ret += gen_endif(var.ifcond)
ret += mcgen('''
default:
abort();
@@ -182,6 +184,7 @@ void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error
c_name=c_name(name))
for var in variants.variants:
+ ret += gen_if(var.ifcond)
ret += mcgen('''
case %(case)s:
''',
@@ -209,6 +212,7 @@ void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error
ret += mcgen('''
break;
''')
+ ret += gen_endif(var.ifcond)
ret += mcgen('''
case QTYPE_NONE:
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 28/50] qapi: add 'if' to alternate variant
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (26 preceding siblings ...)
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 27/50] qapi: add #if conditions to generated variants Marc-André Lureau
@ 2017-09-11 11:06 ` Marc-André Lureau
2017-12-12 14:51 ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 29/50] qapi: add tests for invalid alternate Marc-André Lureau
` (23 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:06 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi.py | 9 ++++++++-
tests/qapi-schema/qapi-schema-test.json | 6 +++++-
tests/qapi-schema/qapi-schema-test.out | 8 +++++++-
3 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 2f14edfa1f..19e48bd4d2 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -849,6 +849,9 @@ def check_alternate(expr, info):
check_type(info, "Member '%s' of alternate '%s'" % (key, name),
value,
allow_metas=['built-in', 'union', 'struct', 'enum'])
+ if isinstance(value, dict):
+ check_unknown_keys(info, value, {'type', 'if'})
+ value = value['type']
qtype = find_alternate_member_qtype(value)
if not qtype:
raise QAPISemError(info, "Alternate '%s' member '%s' cannot use "
@@ -1671,7 +1674,11 @@ class QAPISchema(object):
None))
def _make_variant(self, case, typ):
- return QAPISchemaObjectTypeVariant(case, typ)
+ ifcond = None
+ if isinstance(typ, dict):
+ ifcond = typ.get('if')
+ typ = typ['type']
+ return QAPISchemaObjectTypeVariant(case, typ, ifcond)
def _make_simple_variant(self, case, typ, info):
ifcond = None
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index 895e80a978..f7a62b24d1 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -208,9 +208,13 @@
{ 'command': 'TestIfUnionCmd', 'data': { 'union_cmd_arg': 'TestIfUnion' },
'if': 'defined(TEST_IF_UNION)' }
-{ 'alternate': 'TestIfAlternate', 'data': { 'foo': 'int', 'bar': 'TestStruct' },
+{ 'alternate': 'TestIfAlternate', 'data':
+ { 'foo': 'int', 'alt_bar': { 'type': 'TestStruct', 'if': 'defined(TEST_IF_ALT_BAR)'} },
'if': 'defined(TEST_IF_ALT) && defined(TEST_IF_STRUCT)' }
+{ 'command': 'TestIfAlternateCmd', 'data': { 'alt_cmd_arg': 'TestIfAlternate' },
+ 'if': 'defined(TEST_IF_ALT)' }
+
{ 'command': 'TestIfCmd', 'data':
{ 'foo': 'TestIfStruct',
'bar': { 'type': 'TestIfEnum', 'if': 'defined(TEST_IF_CMD_BAR)' } },
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index ee009c5626..6887e49c9b 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -67,8 +67,11 @@ enum QType
alternate TestIfAlternate
tag type
case foo: int
- case bar: TestStruct
+ case alt_bar: TestStruct if=defined(TEST_IF_ALT_BAR)
if defined(TEST_IF_ALT) && defined(TEST_IF_STRUCT)
+command TestIfAlternateCmd q_obj_TestIfAlternateCmd-arg -> None
+ gen=True success_response=True boxed=False
+ if defined(TEST_IF_ALT)
command TestIfCmd q_obj_TestIfCmd-arg -> None
gen=True success_response=True boxed=False
if defined(TEST_IF_CMD) && defined(TEST_IF_STRUCT)
@@ -232,6 +235,9 @@ object q_obj_EVENT_D-arg
member b: str optional=False
member c: str optional=True
member enum3: EnumOne optional=True
+object q_obj_TestIfAlternateCmd-arg
+ member alt_cmd_arg: TestIfAlternate optional=False
+ if defined(TEST_IF_ALT)
object q_obj_TestIfCmd-arg
member foo: TestIfStruct optional=False
member bar: TestIfEnum optional=False if=defined(TEST_IF_CMD_BAR)
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 29/50] qapi: add tests for invalid alternate
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (27 preceding siblings ...)
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 28/50] qapi: add 'if' to alternate variant Marc-André Lureau
@ 2017-09-11 11:06 ` Marc-André Lureau
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 30/50] qapi: add #if conditions to generated alternate variants Marc-André Lureau
` (22 subsequent siblings)
51 siblings, 0 replies; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:06 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
tests/Makefile.include | 1 +
tests/qapi-schema/alternate-dict-invalid.err | 1 +
tests/qapi-schema/alternate-dict-invalid.exit | 1 +
tests/qapi-schema/alternate-dict-invalid.json | 4 ++++
tests/qapi-schema/alternate-dict-invalid.out | 0
5 files changed, 7 insertions(+)
create mode 100644 tests/qapi-schema/alternate-dict-invalid.err
create mode 100644 tests/qapi-schema/alternate-dict-invalid.exit
create mode 100644 tests/qapi-schema/alternate-dict-invalid.json
create mode 100644 tests/qapi-schema/alternate-dict-invalid.out
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 44a3d8895e..4af0b0c2eb 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -380,6 +380,7 @@ qapi-schema += alternate-conflict-enum-int.json
qapi-schema += alternate-conflict-string.json
qapi-schema += alternate-conflict-bool-string.json
qapi-schema += alternate-conflict-num-string.json
+qapi-schema += alternate-dict-invalid.json
qapi-schema += alternate-empty.json
qapi-schema += alternate-nested.json
qapi-schema += alternate-unknown.json
diff --git a/tests/qapi-schema/alternate-dict-invalid.err b/tests/qapi-schema/alternate-dict-invalid.err
new file mode 100644
index 0000000000..707c40f0f6
--- /dev/null
+++ b/tests/qapi-schema/alternate-dict-invalid.err
@@ -0,0 +1 @@
+tests/qapi-schema/alternate-dict-invalid.json:2: Member 'two' of alternate 'Alt' should be a type name
diff --git a/tests/qapi-schema/alternate-dict-invalid.exit b/tests/qapi-schema/alternate-dict-invalid.exit
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/tests/qapi-schema/alternate-dict-invalid.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/alternate-dict-invalid.json b/tests/qapi-schema/alternate-dict-invalid.json
new file mode 100644
index 0000000000..45f2c8ebef
--- /dev/null
+++ b/tests/qapi-schema/alternate-dict-invalid.json
@@ -0,0 +1,4 @@
+# invalid field dictionnary, missing type
+{ 'alternate': 'Alt',
+ 'data': { 'one': 'str',
+ 'two': { 'if': 'foo' } } }
diff --git a/tests/qapi-schema/alternate-dict-invalid.out b/tests/qapi-schema/alternate-dict-invalid.out
new file mode 100644
index 0000000000..e69de29bb2
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 30/50] qapi: add #if conditions to generated alternate variants
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (28 preceding siblings ...)
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 29/50] qapi: add tests for invalid alternate Marc-André Lureau
@ 2017-09-11 11:06 ` Marc-André Lureau
2017-12-12 19:25 ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 31/50] docs: document schema configuration Marc-André Lureau
` (21 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:06 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
Mostly covered by previous patches already.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi-introspect.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
index ef2d5577db..d6194ff702 100644
--- a/scripts/qapi-introspect.py
+++ b/scripts/qapi-introspect.py
@@ -172,7 +172,7 @@ const QLitObject %(c_name)s = %(c_string)s;
def visit_alternate_type(self, name, info, ifcond, variants):
self._gen_qlit(name, 'alternate',
- {'members': [{'type': self._use_type(m.type)}
+ {'members': [({'type': self._use_type(m.type)}, m.ifcond)
for m in variants.variants]}, ifcond)
def visit_command(self, name, info, ifcond, arg_type, ret_type,
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 31/50] docs: document schema configuration
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (29 preceding siblings ...)
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 30/50] qapi: add #if conditions to generated alternate variants Marc-André Lureau
@ 2017-09-11 11:06 ` Marc-André Lureau
2017-12-13 10:41 ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 32/50] qapi2texi: add 'If:' section to generated documentation Marc-André Lureau
` (20 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:06 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
docs/devel/qapi-code-gen.txt | 37 +++++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt
index 0a90f2278a..24fc6f74ee 100644
--- a/docs/devel/qapi-code-gen.txt
+++ b/docs/devel/qapi-code-gen.txt
@@ -682,6 +682,43 @@ Example: Red Hat, Inc. controls redhat.com, and may therefore add a
downstream command __com.redhat_drive-mirror.
+=== Configuring the schema ===
+
+'struct', 'enum', 'union', 'alternate', 'command' and 'event'
+top-level QAPI expressions can take a 'if' keyword like:
+
+{ 'struct': 'IfStruct', 'data': { 'foo': 'int' },
+ 'if': 'defined(IF_STRUCT) && defined(FOO)' }
+
+Members can be exploded as dictionnary with 'type' & 'if' keys:
+
+{ 'struct': 'IfStruct', 'data':
+ { 'foo': 'int',
+ 'bar': { 'type': 'int', 'if': 'defined(IF_STRUCT_BAR)'} } }
+
+Enum values can be exploded as dictionnary with 'name' & 'if' keys:
+
+{ 'enum': 'IfEnum', 'data':
+ [ 'foo',
+ { 'name' : 'bar', 'if': 'defined(IF_ENUM_BAR)' } ] }
+
+The C code generators will wrap the corresponding lines with #if / #endif
+pre-processor conditions for a given 'if' value.
+
+Example for enum values:
+
+enum IfEnum {
+ IF_ENUM_FOO,
+#if defined(IF_ENUM_BAR)
+ IF_ENUM_BAR,
+#endif /* defined(IF_ENUM_BAR) */
+ IF_ENUM__MAX
+}
+
+Please note that you are responsbile to ensure that the C code will
+compile with an arbitrary combination of conditions, since the
+generators are unable to check it at this point.
+
== Client JSON Protocol introspection ==
Clients of a Client JSON Protocol commonly need to figure out what
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 32/50] qapi2texi: add 'If:' section to generated documentation
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (30 preceding siblings ...)
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 31/50] docs: document schema configuration Marc-André Lureau
@ 2017-09-11 11:06 ` Marc-André Lureau
2017-12-13 12:35 ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 33/50] qapi2texi: add 'If:' condition to enum values Marc-André Lureau
` (19 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:06 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
The documentation is generated only once, and doesn't know C
pre-conditions. Add 'If:' sections for top-level entities.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi2texi.py | 24 +++++++++++++-----------
1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py
index e72e7cfe0b..150e7045d2 100755
--- a/scripts/qapi2texi.py
+++ b/scripts/qapi2texi.py
@@ -132,7 +132,6 @@ def texi_enum_value(value):
"""Format a table of members item for an enumeration value"""
return '@item @code{%s}\n' % value.name
-
def texi_member(member, suffix=''):
"""Format a table of members item for an object type member"""
typ = member.type.doc_type()
@@ -175,7 +174,7 @@ def texi_members(doc, what, base, variants, member_func):
return '\n@b{%s:}\n@table @asis\n%s@end table\n' % (what, items)
-def texi_sections(doc):
+def texi_sections(doc, ifcond):
"""Format additional sections following arguments"""
body = ''
for section in doc.sections:
@@ -189,14 +188,16 @@ def texi_sections(doc):
body += '\n\n@b{%s:}\n' % name
body += func(doc)
+ if ifcond:
+ body += '\n\n@b{If:} @code{%s}' % ifcond
return body
-def texi_entity(doc, what, base=None, variants=None,
+def texi_entity(doc, what, ifcond, base=None, variants=None,
member_func=texi_member):
return (texi_body(doc)
+ texi_members(doc, what, base, variants, member_func)
- + texi_sections(doc))
+ + texi_sections(doc, ifcond))
class QAPISchemaGenDocVisitor(qapi.QAPISchemaVisitor):
@@ -213,7 +214,7 @@ class QAPISchemaGenDocVisitor(qapi.QAPISchemaVisitor):
self.out += '\n'
self.out += TYPE_FMT(type='Enum',
name=doc.symbol,
- body=texi_entity(doc, 'Values',
+ body=texi_entity(doc, 'Values', ifcond,
member_func=texi_enum_value))
def visit_object_type(self, name, info, ifcond, base, members, variants):
@@ -224,7 +225,8 @@ class QAPISchemaGenDocVisitor(qapi.QAPISchemaVisitor):
self.out += '\n'
self.out += TYPE_FMT(type='Object',
name=doc.symbol,
- body=texi_entity(doc, 'Members', base, variants))
+ body=texi_entity(doc, 'Members', ifcond,
+ base, variants))
def visit_alternate_type(self, name, info, ifcond, variants):
doc = self.cur_doc
@@ -232,7 +234,7 @@ class QAPISchemaGenDocVisitor(qapi.QAPISchemaVisitor):
self.out += '\n'
self.out += TYPE_FMT(type='Alternate',
name=doc.symbol,
- body=texi_entity(doc, 'Members'))
+ body=texi_entity(doc, 'Members', ifcond))
def visit_command(self, name, info, ifcond, arg_type, ret_type,
gen, success_response, boxed):
@@ -242,9 +244,9 @@ class QAPISchemaGenDocVisitor(qapi.QAPISchemaVisitor):
if boxed:
body = texi_body(doc)
body += '\n@b{Arguments:} the members of @code{%s}' % arg_type.name
- body += texi_sections(doc)
+ body += texi_sections(doc, ifcond)
else:
- body = texi_entity(doc, 'Arguments')
+ body = texi_entity(doc, 'Arguments', ifcond)
self.out += MSG_FMT(type='Command',
name=doc.symbol,
body=body)
@@ -255,7 +257,7 @@ class QAPISchemaGenDocVisitor(qapi.QAPISchemaVisitor):
self.out += '\n'
self.out += MSG_FMT(type='Event',
name=doc.symbol,
- body=texi_entity(doc, 'Arguments'))
+ body=texi_entity(doc, 'Arguments', ifcond))
def symbol(self, doc, entity):
self.cur_doc = doc
@@ -266,7 +268,7 @@ class QAPISchemaGenDocVisitor(qapi.QAPISchemaVisitor):
assert not doc.args
if self.out:
self.out += '\n'
- self.out += texi_body(doc) + texi_sections(doc)
+ self.out += texi_body(doc) + texi_sections(doc, None)
def texi_schema(schema):
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 33/50] qapi2texi: add 'If:' condition to enum values
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (31 preceding siblings ...)
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 32/50] qapi2texi: add 'If:' section to generated documentation Marc-André Lureau
@ 2017-09-11 11:06 ` Marc-André Lureau
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 34/50] qapi2texi: add 'If:' condition to struct members Marc-André Lureau
` (18 subsequent siblings)
51 siblings, 0 replies; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:06 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi2texi.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py
index 150e7045d2..7327245a60 100755
--- a/scripts/qapi2texi.py
+++ b/scripts/qapi2texi.py
@@ -130,7 +130,9 @@ def texi_body(doc):
def texi_enum_value(value):
"""Format a table of members item for an enumeration value"""
- return '@item @code{%s}\n' % value.name
+ return '@item @code{%s}%s\n' % (
+ value.name,
+ '\n@b{If:} @code{%s}\n' % value.ifcond if value.ifcond else '')
def texi_member(member, suffix=''):
"""Format a table of members item for an object type member"""
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 34/50] qapi2texi: add 'If:' condition to struct members
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (32 preceding siblings ...)
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 33/50] qapi2texi: add 'If:' condition to enum values Marc-André Lureau
@ 2017-09-11 11:06 ` Marc-André Lureau
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 35/50] qapi2texi: add condition to variants Marc-André Lureau
` (17 subsequent siblings)
51 siblings, 0 replies; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:06 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi2texi.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py
index 7327245a60..bb819856ef 100755
--- a/scripts/qapi2texi.py
+++ b/scripts/qapi2texi.py
@@ -138,9 +138,10 @@ def texi_member(member, suffix=''):
"""Format a table of members item for an object type member"""
typ = member.type.doc_type()
membertype = ': ' + typ if typ else ''
- return '@item @code{%s%s}%s%s\n' % (
+ return '@item @code{%s%s}%s%s%s\n' % (
member.name, membertype,
' (optional)' if member.optional else '',
+ '\n@b{If:} @code{%s}\n' % member.ifcond if member.ifcond else '',
suffix)
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 35/50] qapi2texi: add condition to variants
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (33 preceding siblings ...)
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 34/50] qapi2texi: add 'If:' condition to struct members Marc-André Lureau
@ 2017-09-11 11:06 ` Marc-André Lureau
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 36/50] qapi: add conditions to VNC type/commands/events on the schema Marc-André Lureau
` (16 subsequent siblings)
51 siblings, 0 replies; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:06 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi2texi.py | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py
index bb819856ef..4e7b1cda87 100755
--- a/scripts/qapi2texi.py
+++ b/scripts/qapi2texi.py
@@ -163,8 +163,9 @@ def texi_members(doc, what, base, variants, member_func):
items += '@item The members of @code{%s}\n' % base.doc_type()
if variants:
for v in variants.variants:
- when = ' when @code{%s} is @t{"%s"}' % (
- variants.tag_member.name, v.name)
+ when = ' when @code{%s} is @t{"%s"}%s' % (
+ variants.tag_member.name, v.name,
+ ' (and @code{%s})' % v.ifcond if v.ifcond else '')
if v.type.is_implicit():
assert not v.type.base and not v.type.variants
for m in v.type.local_members:
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 36/50] qapi: add conditions to VNC type/commands/events on the schema
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (34 preceding siblings ...)
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 35/50] qapi2texi: add condition to variants Marc-André Lureau
@ 2017-09-11 11:06 ` Marc-André Lureau
2017-12-13 14:12 ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 37/50] qapi: add conditions to SPICE " Marc-André Lureau
` (15 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:06 UTC (permalink / raw)
To: qemu-devel
Cc: armbru, Marc-André Lureau, Daniel P. Berrange,
Dr. David Alan Gilbert, Eric Blake, Gerd Hoffmann
Add #if defined(CONFIG_VNC) in generated code, and adjust the
qmp/hmp code accordingly.
Commands made conditional:
* query-vnc, query-vnc-servers, change-vnc-password
Before the patch, the commands for !CONFIG_VNC are stubs that fail
like this:
{"error": {"class": "GenericError",
"desc": "The feature 'vnc' is not enabled"}}
Afterwards, they fail like this:
{"error": {"class": "CommandNotFound",
"desc": "The command FOO has not been found"}}
I call that an improvement, because it lets clients distinguish
between command unavailable (class CommandNotFound) and command failed
(class GenericError).
Events made conditional:
* VNC_CONNECTED, VNC_INITIALIZED, VNC_DISCONNECTED
Enum made conditional:
* QCryptoCipherAlgorithm
# @des-rfb: RFB specific variant of single DES. Do not use except in VNC.
Occurrences of VNC (case insensitive) in the schema that aren't
covered by this change:
* add_client
Command has other uses, including "socket bases character devices".
These are unconditional as far as I can tell.
* set_password, expire_password
In theory, these commands could be used for managing any service's
password. In practice, they're used for VNC and SPICE services.
They're documented for "remote display session" / "remote display
server".
The service is selected by argument @protocol. The code special-cases
protocol-specific argument checking, then calls a protocol-specific
function to do the work. If it fails, the command fails with "Could
not set password". It does when the service isn't compiled in (it's a
stub then).
We could make these commands conditional on the conjunction of all
services [currently: defined(CONFIG_VNC) || defined(CONFIG_SPICE)],
but I doubt it's worthwhile.
* change
Command has other uses, namely changing media.
This patch inlines a stub; no functional change.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qapi/crypto.json | 3 ++-
qapi/ui.json | 45 ++++++++++++++++++++++++++++-----------------
ui/vnc.h | 2 ++
crypto/cipher-builtin.c | 9 +++++++++
crypto/cipher-gcrypt.c | 10 ++++++++--
crypto/cipher-nettle.c | 14 +++++++++++---
crypto/cipher.c | 13 +++++++++++--
hmp.c | 9 ++++++++-
qmp.c | 30 ++++--------------------------
tests/test-crypto-cipher.c | 2 ++
hmp-commands-info.hx | 2 ++
11 files changed, 87 insertions(+), 52 deletions(-)
diff --git a/qapi/crypto.json b/qapi/crypto.json
index 288bc056ef..09535b7be2 100644
--- a/qapi/crypto.json
+++ b/qapi/crypto.json
@@ -79,7 +79,8 @@
{ 'enum': 'QCryptoCipherAlgorithm',
'prefix': 'QCRYPTO_CIPHER_ALG',
'data': ['aes-128', 'aes-192', 'aes-256',
- 'des-rfb', '3des',
+ { 'name': 'des-rfb', 'if': 'defined(CONFIG_VNC)' },
+ '3des',
'cast5-128',
'serpent-128', 'serpent-192', 'serpent-256',
'twofish-128', 'twofish-192', 'twofish-256']}
diff --git a/qapi/ui.json b/qapi/ui.json
index e5d6610b4a..4b573d214b 100644
--- a/qapi/ui.json
+++ b/qapi/ui.json
@@ -369,7 +369,8 @@
'data': { 'host': 'str',
'service': 'str',
'family': 'NetworkAddressFamily',
- 'websocket': 'bool' } }
+ 'websocket': 'bool' },
+ 'if': 'defined(CONFIG_VNC)' }
##
# @VncServerInfo:
@@ -383,7 +384,8 @@
##
{ 'struct': 'VncServerInfo',
'base': 'VncBasicInfo',
- 'data': { '*auth': 'str' } }
+ 'data': { '*auth': 'str' },
+ 'if': 'defined(CONFIG_VNC)' }
##
# @VncClientInfo:
@@ -400,7 +402,8 @@
##
{ 'struct': 'VncClientInfo',
'base': 'VncBasicInfo',
- 'data': { '*x509_dname': 'str', '*sasl_username': 'str' } }
+ 'data': { '*x509_dname': 'str', '*sasl_username': 'str' },
+ 'if': 'defined(CONFIG_VNC)' }
##
# @VncInfo:
@@ -441,7 +444,8 @@
{ 'struct': 'VncInfo',
'data': {'enabled': 'bool', '*host': 'str',
'*family': 'NetworkAddressFamily',
- '*service': 'str', '*auth': 'str', '*clients': ['VncClientInfo']} }
+ '*service': 'str', '*auth': 'str', '*clients': ['VncClientInfo']},
+ 'if': 'defined(CONFIG_VNC)' }
##
# @VncPrimaryAuth:
@@ -452,7 +456,8 @@
##
{ 'enum': 'VncPrimaryAuth',
'data': [ 'none', 'vnc', 'ra2', 'ra2ne', 'tight', 'ultra',
- 'tls', 'vencrypt', 'sasl' ] }
+ 'tls', 'vencrypt', 'sasl' ],
+ 'if': 'defined(CONFIG_VNC)' }
##
# @VncVencryptSubAuth:
@@ -466,8 +471,8 @@
'tls-none', 'x509-none',
'tls-vnc', 'x509-vnc',
'tls-plain', 'x509-plain',
- 'tls-sasl', 'x509-sasl' ] }
-
+ 'tls-sasl', 'x509-sasl' ],
+ 'if': 'defined(CONFIG_VNC)' }
##
# @VncServerInfo2:
@@ -484,8 +489,8 @@
{ 'struct': 'VncServerInfo2',
'base': 'VncBasicInfo',
'data': { 'auth' : 'VncPrimaryAuth',
- '*vencrypt' : 'VncVencryptSubAuth' } }
-
+ '*vencrypt' : 'VncVencryptSubAuth' },
+ 'if': 'defined(CONFIG_VNC)' }
##
# @VncInfo2:
@@ -517,7 +522,8 @@
'clients' : ['VncClientInfo'],
'auth' : 'VncPrimaryAuth',
'*vencrypt' : 'VncVencryptSubAuth',
- '*display' : 'str' } }
+ '*display' : 'str' },
+ 'if': 'defined(CONFIG_VNC)' }
##
# @query-vnc:
@@ -548,8 +554,8 @@
# }
#
##
-{ 'command': 'query-vnc', 'returns': 'VncInfo' }
-
+{ 'command': 'query-vnc', 'returns': 'VncInfo',
+ 'if': 'defined(CONFIG_VNC)' }
##
# @query-vnc-servers:
#
@@ -559,7 +565,8 @@
#
# Since: 2.3
##
-{ 'command': 'query-vnc-servers', 'returns': ['VncInfo2'] }
+{ 'command': 'query-vnc-servers', 'returns': ['VncInfo2'],
+ 'if': 'defined(CONFIG_VNC)' }
##
# @change-vnc-password:
@@ -573,7 +580,8 @@
# Notes: An empty password in this command will set the password to the empty
# string. Existing clients are unaffected by executing this command.
##
-{ 'command': 'change-vnc-password', 'data': {'password': 'str'} }
+{ 'command': 'change-vnc-password', 'data': {'password': 'str'},
+ 'if': 'defined(CONFIG_VNC)' }
##
# @VNC_CONNECTED:
@@ -602,7 +610,8 @@
##
{ 'event': 'VNC_CONNECTED',
'data': { 'server': 'VncServerInfo',
- 'client': 'VncBasicInfo' } }
+ 'client': 'VncBasicInfo' },
+ 'if': 'defined(CONFIG_VNC)' }
##
# @VNC_INITIALIZED:
@@ -629,7 +638,8 @@
##
{ 'event': 'VNC_INITIALIZED',
'data': { 'server': 'VncServerInfo',
- 'client': 'VncClientInfo' } }
+ 'client': 'VncClientInfo' },
+ 'if': 'defined(CONFIG_VNC)' }
##
# @VNC_DISCONNECTED:
@@ -655,7 +665,8 @@
##
{ 'event': 'VNC_DISCONNECTED',
'data': { 'server': 'VncServerInfo',
- 'client': 'VncClientInfo' } }
+ 'client': 'VncClientInfo' },
+ 'if': 'defined(CONFIG_VNC)' }
##
# = Input
diff --git a/ui/vnc.h b/ui/vnc.h
index 694cf32ca9..5572bfdc9e 100644
--- a/ui/vnc.h
+++ b/ui/vnc.h
@@ -291,7 +291,9 @@ struct VncState
bool encode_ws;
bool websocket;
+#ifdef CONFIG_VNC
VncClientInfo *info;
+#endif
Buffer output;
Buffer input;
diff --git a/crypto/cipher-builtin.c b/crypto/cipher-builtin.c
index d8c811fd33..647850843e 100644
--- a/crypto/cipher-builtin.c
+++ b/crypto/cipher-builtin.c
@@ -35,17 +35,22 @@ struct QCryptoCipherBuiltinAES {
QCryptoCipherBuiltinAESContext key_tweak;
uint8_t iv[AES_BLOCK_SIZE];
};
+
+#ifdef CONFIG_VNC
typedef struct QCryptoCipherBuiltinDESRFB QCryptoCipherBuiltinDESRFB;
struct QCryptoCipherBuiltinDESRFB {
uint8_t *key;
size_t nkey;
};
+#endif
typedef struct QCryptoCipherBuiltin QCryptoCipherBuiltin;
struct QCryptoCipherBuiltin {
union {
QCryptoCipherBuiltinAES aes;
+#ifdef CONFIG_VNC
QCryptoCipherBuiltinDESRFB desrfb;
+#endif
} state;
size_t blocksize;
void (*free)(QCryptoCipher *cipher);
@@ -403,7 +408,9 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
QCryptoCipherMode mode)
{
switch (alg) {
+#ifdef CONFIG_VNC
case QCRYPTO_CIPHER_ALG_DES_RFB:
+#endif
case QCRYPTO_CIPHER_ALG_AES_128:
case QCRYPTO_CIPHER_ALG_AES_192:
case QCRYPTO_CIPHER_ALG_AES_256:
@@ -449,9 +456,11 @@ static QCryptoCipherBuiltin *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
}
switch (alg) {
+#ifdef CONFIG_VNC
case QCRYPTO_CIPHER_ALG_DES_RFB:
ctxt = qcrypto_cipher_init_des_rfb(mode, key, nkey, errp);
break;
+#endif
case QCRYPTO_CIPHER_ALG_AES_128:
case QCRYPTO_CIPHER_ALG_AES_192:
case QCRYPTO_CIPHER_ALG_AES_256:
diff --git a/crypto/cipher-gcrypt.c b/crypto/cipher-gcrypt.c
index 10d75da75d..c240aaee26 100644
--- a/crypto/cipher-gcrypt.c
+++ b/crypto/cipher-gcrypt.c
@@ -29,7 +29,9 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
QCryptoCipherMode mode)
{
switch (alg) {
+#ifdef CONFIG_VNC
case QCRYPTO_CIPHER_ALG_DES_RFB:
+#endif
case QCRYPTO_CIPHER_ALG_3DES:
case QCRYPTO_CIPHER_ALG_AES_128:
case QCRYPTO_CIPHER_ALG_AES_192:
@@ -114,10 +116,11 @@ static QCryptoCipherGcrypt *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
}
switch (alg) {
+#ifdef CONFIG_VNC
case QCRYPTO_CIPHER_ALG_DES_RFB:
gcryalg = GCRY_CIPHER_DES;
break;
-
+#endif
case QCRYPTO_CIPHER_ALG_3DES:
gcryalg = GCRY_CIPHER_3DES;
break;
@@ -181,6 +184,7 @@ static QCryptoCipherGcrypt *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
}
}
+#ifdef CONFIG_VNC
if (alg == QCRYPTO_CIPHER_ALG_DES_RFB) {
/* We're using standard DES cipher from gcrypt, so we need
* to munge the key so that the results are the same as the
@@ -190,7 +194,9 @@ static QCryptoCipherGcrypt *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
err = gcry_cipher_setkey(ctx->handle, rfbkey, nkey);
g_free(rfbkey);
ctx->blocksize = 8;
- } else {
+ } else
+#endif /* CONFIG_VNC */
+ {
if (mode == QCRYPTO_CIPHER_MODE_XTS) {
nkey /= 2;
err = gcry_cipher_setkey(ctx->handle, key, nkey);
diff --git a/crypto/cipher-nettle.c b/crypto/cipher-nettle.c
index 3848cb3b3a..ace5ec20f6 100644
--- a/crypto/cipher-nettle.c
+++ b/crypto/cipher-nettle.c
@@ -67,6 +67,7 @@ static void aes_decrypt_native(cipher_ctx_t ctx, cipher_length_t length,
aes_decrypt(&aesctx->dec, length, dst, src);
}
+#ifdef CONFIG_VNC
static void des_encrypt_native(cipher_ctx_t ctx, cipher_length_t length,
uint8_t *dst, const uint8_t *src)
{
@@ -78,6 +79,7 @@ static void des_decrypt_native(cipher_ctx_t ctx, cipher_length_t length,
{
des_decrypt(ctx, length, dst, src);
}
+#endif
static void des3_encrypt_native(cipher_ctx_t ctx, cipher_length_t length,
uint8_t *dst, const uint8_t *src)
@@ -141,6 +143,7 @@ static void aes_decrypt_wrapper(const void *ctx, size_t length,
aes_decrypt(&aesctx->dec, length, dst, src);
}
+#ifdef CONFIG_VNC
static void des_encrypt_wrapper(const void *ctx, size_t length,
uint8_t *dst, const uint8_t *src)
{
@@ -152,6 +155,7 @@ static void des_decrypt_wrapper(const void *ctx, size_t length,
{
des_decrypt(ctx, length, dst, src);
}
+#endif
static void des3_encrypt_wrapper(const void *ctx, size_t length,
uint8_t *dst, const uint8_t *src)
@@ -221,7 +225,9 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
QCryptoCipherMode mode)
{
switch (alg) {
+#ifdef CONFIG_VNC
case QCRYPTO_CIPHER_ALG_DES_RFB:
+#endif
case QCRYPTO_CIPHER_ALG_3DES:
case QCRYPTO_CIPHER_ALG_AES_128:
case QCRYPTO_CIPHER_ALG_AES_192:
@@ -271,7 +277,6 @@ static QCryptoCipherNettle *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
Error **errp)
{
QCryptoCipherNettle *ctx;
- uint8_t *rfbkey;
switch (mode) {
case QCRYPTO_CIPHER_MODE_ECB:
@@ -292,7 +297,9 @@ static QCryptoCipherNettle *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
ctx = g_new0(QCryptoCipherNettle, 1);
switch (alg) {
- case QCRYPTO_CIPHER_ALG_DES_RFB:
+#ifdef CONFIG_VNC
+ case QCRYPTO_CIPHER_ALG_DES_RFB: {
+ uint8_t *rfbkey;
ctx->ctx = g_new0(struct des_ctx, 1);
rfbkey = qcrypto_cipher_munge_des_rfb_key(key, nkey);
des_set_key(ctx->ctx, rfbkey);
@@ -305,7 +312,8 @@ static QCryptoCipherNettle *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
ctx->blocksize = DES_BLOCK_SIZE;
break;
-
+ }
+#endif
case QCRYPTO_CIPHER_ALG_3DES:
ctx->ctx = g_new0(struct des3_ctx, 1);
des3_set_key(ctx->ctx, key);
diff --git a/crypto/cipher.c b/crypto/cipher.c
index 0aad9d6d79..80355f4530 100644
--- a/crypto/cipher.c
+++ b/crypto/cipher.c
@@ -28,7 +28,9 @@ static size_t alg_key_len[QCRYPTO_CIPHER_ALG__MAX] = {
[QCRYPTO_CIPHER_ALG_AES_128] = 16,
[QCRYPTO_CIPHER_ALG_AES_192] = 24,
[QCRYPTO_CIPHER_ALG_AES_256] = 32,
+#ifdef CONFIG_VNC
[QCRYPTO_CIPHER_ALG_DES_RFB] = 8,
+#endif
[QCRYPTO_CIPHER_ALG_3DES] = 24,
[QCRYPTO_CIPHER_ALG_CAST5_128] = 16,
[QCRYPTO_CIPHER_ALG_SERPENT_128] = 16,
@@ -43,7 +45,9 @@ static size_t alg_block_len[QCRYPTO_CIPHER_ALG__MAX] = {
[QCRYPTO_CIPHER_ALG_AES_128] = 16,
[QCRYPTO_CIPHER_ALG_AES_192] = 16,
[QCRYPTO_CIPHER_ALG_AES_256] = 16,
+#ifdef CONFIG_VNC
[QCRYPTO_CIPHER_ALG_DES_RFB] = 8,
+#endif
[QCRYPTO_CIPHER_ALG_3DES] = 8,
[QCRYPTO_CIPHER_ALG_CAST5_128] = 8,
[QCRYPTO_CIPHER_ALG_SERPENT_128] = 16,
@@ -106,8 +110,11 @@ qcrypto_cipher_validate_key_length(QCryptoCipherAlgorithm alg,
}
if (mode == QCRYPTO_CIPHER_MODE_XTS) {
- if (alg == QCRYPTO_CIPHER_ALG_DES_RFB
- || alg == QCRYPTO_CIPHER_ALG_3DES) {
+ if (
+#ifdef CONFIG_VNC
+ alg == QCRYPTO_CIPHER_ALG_DES_RFB ||
+#endif
+ alg == QCRYPTO_CIPHER_ALG_3DES) {
error_setg(errp, "XTS mode not compatible with DES-RFB/3DES");
return false;
}
@@ -131,6 +138,7 @@ qcrypto_cipher_validate_key_length(QCryptoCipherAlgorithm alg,
return true;
}
+#if defined(CONFIG_VNC)
#if defined(CONFIG_GCRYPT) || defined(CONFIG_NETTLE)
static uint8_t *
qcrypto_cipher_munge_des_rfb_key(const uint8_t *key,
@@ -148,6 +156,7 @@ qcrypto_cipher_munge_des_rfb_key(const uint8_t *key,
return ret;
}
#endif /* CONFIG_GCRYPT || CONFIG_NETTLE */
+#endif /* CONFIG_VNC */
#ifdef CONFIG_GCRYPT
#include "crypto/cipher-gcrypt.c"
diff --git a/hmp.c b/hmp.c
index cd046c6d71..5893e5bf16 100644
--- a/hmp.c
+++ b/hmp.c
@@ -604,6 +604,7 @@ void hmp_info_blockstats(Monitor *mon, const QDict *qdict)
qapi_free_BlockStatsList(stats_list);
}
+#ifdef CONFIG_VNC
/* Helper for hmp_info_vnc_clients, _servers */
static void hmp_info_VncBasicInfo(Monitor *mon, VncBasicInfo *info,
const char *name)
@@ -691,6 +692,7 @@ void hmp_info_vnc(Monitor *mon, const QDict *qdict)
qapi_free_VncInfo2List(info2l);
}
+#endif
#ifdef CONFIG_SPICE
void hmp_info_spice(Monitor *mon, const QDict *qdict)
@@ -1702,12 +1704,14 @@ void hmp_eject(Monitor *mon, const QDict *qdict)
hmp_handle_error(mon, &err);
}
+#ifdef CONFIG_VNC
static void hmp_change_read_arg(void *opaque, const char *password,
void *readline_opaque)
{
qmp_change_vnc_password(password, NULL);
monitor_read_command(opaque, 1);
}
+#endif
void hmp_change(Monitor *mon, const QDict *qdict)
{
@@ -1718,6 +1722,7 @@ void hmp_change(Monitor *mon, const QDict *qdict)
BlockdevChangeReadOnlyMode read_only_mode = 0;
Error *err = NULL;
+#ifdef CONFIG_VNC
if (strcmp(device, "vnc") == 0) {
if (read_only) {
monitor_printf(mon,
@@ -1732,7 +1737,9 @@ void hmp_change(Monitor *mon, const QDict *qdict)
}
}
qmp_change("vnc", target, !!arg, arg, &err);
- } else {
+ } else
+#endif
+ {
if (read_only) {
read_only_mode =
qapi_enum_parse(&BlockdevChangeReadOnlyMode_lookup,
diff --git a/qmp.c b/qmp.c
index b86201e349..2c90dacb56 100644
--- a/qmp.c
+++ b/qmp.c
@@ -130,22 +130,6 @@ void qmp_cpu_add(int64_t id, Error **errp)
}
}
-#ifndef CONFIG_VNC
-/* If VNC support is enabled, the "true" query-vnc command is
- defined in the VNC subsystem */
-VncInfo *qmp_query_vnc(Error **errp)
-{
- error_setg(errp, QERR_FEATURE_DISABLED, "vnc");
- return NULL;
-};
-
-VncInfo2List *qmp_query_vnc_servers(Error **errp)
-{
- error_setg(errp, QERR_FEATURE_DISABLED, "vnc");
- return NULL;
-};
-#endif
-
#ifndef CONFIG_SPICE
/*
* qmp-commands.hx ensures that QMP command query-spice exists only
@@ -403,23 +387,17 @@ static void qmp_change_vnc(const char *target, bool has_arg, const char *arg,
qmp_change_vnc_listen(target, errp);
}
}
-#else
-void qmp_change_vnc_password(const char *password, Error **errp)
-{
- error_setg(errp, QERR_FEATURE_DISABLED, "vnc");
-}
-static void qmp_change_vnc(const char *target, bool has_arg, const char *arg,
- Error **errp)
-{
- error_setg(errp, QERR_FEATURE_DISABLED, "vnc");
-}
#endif /* !CONFIG_VNC */
void qmp_change(const char *device, const char *target,
bool has_arg, const char *arg, Error **errp)
{
if (strcmp(device, "vnc") == 0) {
+#ifdef CONFIG_VNC
qmp_change_vnc(target, has_arg, arg, errp);
+#else
+ error_setg(errp, QERR_FEATURE_DISABLED, "vnc");
+#endif
} else {
qmp_blockdev_change_medium(true, device, false, NULL, target,
has_arg, arg, false, 0, errp);
diff --git a/tests/test-crypto-cipher.c b/tests/test-crypto-cipher.c
index 07fa2fa616..5980b27389 100644
--- a/tests/test-crypto-cipher.c
+++ b/tests/test-crypto-cipher.c
@@ -149,6 +149,7 @@ static QCryptoCipherTestData test_data[] = {
"39f23369a9d9bacfa530e26304231461"
"b2eb05e2c39be9fcda6c19078c6a9d1b",
},
+#ifdef CONFIG_VNC
{
.path = "/crypto/cipher/des-rfb-ecb-56",
.alg = QCRYPTO_CIPHER_ALG_DES_RFB,
@@ -165,6 +166,7 @@ static QCryptoCipherTestData test_data[] = {
"ffd29f1bb5596ad94ea2d8e6196b7f09"
"30d8ed0bf2773af36dd82a6280c20926",
},
+#endif
#if defined(CONFIG_NETTLE) || defined(CONFIG_GCRYPT)
{
/* Borrowed from linux-kernel crypto/testmgr.h */
diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
index 4ab7fcee98..aece8c5999 100644
--- a/hmp-commands-info.hx
+++ b/hmp-commands-info.hx
@@ -420,6 +420,7 @@ STEXI
Show which guest mouse is receiving events.
ETEXI
+#if defined(CONFIG_VNC)
{
.name = "vnc",
.args_type = "",
@@ -427,6 +428,7 @@ ETEXI
.help = "show the vnc server status",
.cmd = hmp_info_vnc,
},
+#endif
STEXI
@item info vnc
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 37/50] qapi: add conditions to SPICE type/commands/events on the schema
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (35 preceding siblings ...)
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 36/50] qapi: add conditions to VNC type/commands/events on the schema Marc-André Lureau
@ 2017-09-11 11:06 ` Marc-André Lureau
2017-12-13 14:17 ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 38/50] qapi: add conditions to REPLICATION type/commands " Marc-André Lureau
` (14 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:06 UTC (permalink / raw)
To: qemu-devel
Cc: armbru, Marc-André Lureau, Dr. David Alan Gilbert,
Paolo Bonzini, Eric Blake, Gerd Hoffmann
Add #if defined(CONFIG_SPICE) in generated code, and adjust the
qmp/hmp code accordingly.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qapi/char.json | 10 ++++++----
qapi/ui.json | 30 ++++++++++++++++++++----------
monitor.c | 3 ---
qmp.c | 16 ----------------
4 files changed, 26 insertions(+), 33 deletions(-)
diff --git a/qapi/char.json b/qapi/char.json
index ae19dcd1ed..7fa1762ae5 100644
--- a/qapi/char.json
+++ b/qapi/char.json
@@ -318,7 +318,8 @@
# Since: 1.5
##
{ 'struct': 'ChardevSpiceChannel', 'data': { 'type' : 'str' },
- 'base': 'ChardevCommon' }
+ 'base': 'ChardevCommon',
+ 'if': 'defined(CONFIG_SPICE)' }
##
# @ChardevSpicePort:
@@ -330,7 +331,8 @@
# Since: 1.5
##
{ 'struct': 'ChardevSpicePort', 'data': { 'fqdn' : 'str' },
- 'base': 'ChardevCommon' }
+ 'base': 'ChardevCommon',
+ 'if': 'defined(CONFIG_SPICE)' }
##
# @ChardevVC:
@@ -384,8 +386,8 @@
'testdev': 'ChardevCommon',
'stdio' : 'ChardevStdio',
'console': 'ChardevCommon',
- 'spicevmc' : 'ChardevSpiceChannel',
- 'spiceport' : 'ChardevSpicePort',
+ 'spicevmc' : { 'type': 'ChardevSpiceChannel', 'if': 'defined(CONFIG_SPICE)' },
+ 'spiceport' : { 'type': 'ChardevSpicePort', 'if': 'defined(CONFIG_SPICE)' },
'vc' : 'ChardevVC',
'ringbuf': 'ChardevRingbuf',
# next one is just for compatibility
diff --git a/qapi/ui.json b/qapi/ui.json
index 4b573d214b..daa4168c14 100644
--- a/qapi/ui.json
+++ b/qapi/ui.json
@@ -110,7 +110,8 @@
{ 'struct': 'SpiceBasicInfo',
'data': { 'host': 'str',
'port': 'str',
- 'family': 'NetworkAddressFamily' } }
+ 'family': 'NetworkAddressFamily' },
+ 'if': 'defined(CONFIG_SPICE)' }
##
# @SpiceServerInfo:
@@ -123,7 +124,8 @@
##
{ 'struct': 'SpiceServerInfo',
'base': 'SpiceBasicInfo',
- 'data': { '*auth': 'str' } }
+ 'data': { '*auth': 'str' },
+ 'if': 'defined(CONFIG_SPICE)' }
##
# @SpiceChannel:
@@ -148,7 +150,8 @@
{ 'struct': 'SpiceChannel',
'base': 'SpiceBasicInfo',
'data': {'connection-id': 'int', 'channel-type': 'int', 'channel-id': 'int',
- 'tls': 'bool'} }
+ 'tls': 'bool'},
+ 'if': 'defined(CONFIG_SPICE)' }
##
# @SpiceQueryMouseMode:
@@ -167,7 +170,8 @@
# Since: 1.1
##
{ 'enum': 'SpiceQueryMouseMode',
- 'data': [ 'client', 'server', 'unknown' ] }
+ 'data': [ 'client', 'server', 'unknown' ],
+ 'if': 'defined(CONFIG_SPICE)' }
##
# @SpiceInfo:
@@ -204,7 +208,8 @@
{ 'struct': 'SpiceInfo',
'data': {'enabled': 'bool', 'migrated': 'bool', '*host': 'str', '*port': 'int',
'*tls-port': 'int', '*auth': 'str', '*compiled-version': 'str',
- 'mouse-mode': 'SpiceQueryMouseMode', '*channels': ['SpiceChannel']} }
+ 'mouse-mode': 'SpiceQueryMouseMode', '*channels': ['SpiceChannel']},
+ 'if': 'defined(CONFIG_SPICE)' }
##
# @query-spice:
@@ -249,7 +254,8 @@
# }
#
##
-{ 'command': 'query-spice', 'returns': 'SpiceInfo' }
+{ 'command': 'query-spice', 'returns': 'SpiceInfo',
+ 'if': 'defined(CONFIG_SPICE)' }
##
# @SPICE_CONNECTED:
@@ -274,7 +280,8 @@
##
{ 'event': 'SPICE_CONNECTED',
'data': { 'server': 'SpiceBasicInfo',
- 'client': 'SpiceBasicInfo' } }
+ 'client': 'SpiceBasicInfo' },
+ 'if': 'defined(CONFIG_SPICE)' }
##
# @SPICE_INITIALIZED:
@@ -302,7 +309,8 @@
##
{ 'event': 'SPICE_INITIALIZED',
'data': { 'server': 'SpiceServerInfo',
- 'client': 'SpiceChannel' } }
+ 'client': 'SpiceChannel' },
+ 'if': 'defined(CONFIG_SPICE)' }
##
# @SPICE_DISCONNECTED:
@@ -327,7 +335,8 @@
##
{ 'event': 'SPICE_DISCONNECTED',
'data': { 'server': 'SpiceBasicInfo',
- 'client': 'SpiceBasicInfo' } }
+ 'client': 'SpiceBasicInfo' },
+ 'if': 'defined(CONFIG_SPICE)' }
##
# @SPICE_MIGRATE_COMPLETED:
@@ -342,7 +351,8 @@
# "event": "SPICE_MIGRATE_COMPLETED" }
#
##
-{ 'event': 'SPICE_MIGRATE_COMPLETED' }
+{ 'event': 'SPICE_MIGRATE_COMPLETED',
+ 'if': 'defined(CONFIG_SPICE)' }
##
# == VNC
diff --git a/monitor.c b/monitor.c
index 5685697f59..135a1e0821 100644
--- a/monitor.c
+++ b/monitor.c
@@ -970,9 +970,6 @@ static void qmp_query_qmp_schema(QDict *qdict, QObject **ret_data,
*/
static void qmp_unregister_commands_hack(void)
{
-#ifndef CONFIG_SPICE
- qmp_unregister_command(&qmp_commands, "query-spice");
-#endif
#ifndef CONFIG_REPLICATION
qmp_unregister_command(&qmp_commands, "xen-set-replication");
qmp_unregister_command(&qmp_commands, "query-xen-replication-status");
diff --git a/qmp.c b/qmp.c
index 2c90dacb56..90816ba283 100644
--- a/qmp.c
+++ b/qmp.c
@@ -130,22 +130,6 @@ void qmp_cpu_add(int64_t id, Error **errp)
}
}
-#ifndef CONFIG_SPICE
-/*
- * qmp-commands.hx ensures that QMP command query-spice exists only
- * #ifdef CONFIG_SPICE. Necessary for an accurate query-commands
- * result. However, the QAPI schema is blissfully unaware of that,
- * and the QAPI code generator happily generates a dead
- * qmp_marshal_query_spice() that calls qmp_query_spice(). Provide it
- * one, or else linking fails. FIXME Educate the QAPI schema on
- * CONFIG_SPICE.
- */
-SpiceInfo *qmp_query_spice(Error **errp)
-{
- abort();
-};
-#endif
-
void qmp_cont(Error **errp)
{
BlockBackend *blk;
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 38/50] qapi: add conditions to REPLICATION type/commands on the schema
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (36 preceding siblings ...)
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 37/50] qapi: add conditions to SPICE " Marc-André Lureau
@ 2017-09-11 11:06 ` Marc-André Lureau
2017-12-13 14:19 ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 39/50] qapi-commands: don't initialize command list in qmp_init_marshall() Marc-André Lureau
` (13 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:06 UTC (permalink / raw)
To: qemu-devel
Cc: armbru, Marc-André Lureau, zhanghailiang, Juan Quintela,
Dr. David Alan Gilbert, Eric Blake
Add #if defined(CONFIG_REPLICATION) in generated code, and adjust the
code accordingly.
Made conditional:
* xen-set-replication, query-xen-replication-status,
xen-colo-do-checkpoint
Before the patch, we first register the commands unconditionally in
generated code (requires a stub), then conditionally unregister in
qmp_unregister_commands_hack().
Afterwards, we register only when CONFIG_REPLICATION. The command
fails exactly the same, with CommandNotFound.
Improvement, because now query-qmp-schema is accurate, and we're one
step close to killing qmp_unregister_commands_hack().
* enum BlockdevDriver value "replication" in command blockdev-add
As well as enum BlockdevDriver value @replication BlockdevOptions
variant @replication, BlockdevOptionsReplication,
BlockdevOptionsReplicationMode.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qapi/block-core.json | 15 ++++++++++-----
qapi/migration.json | 12 ++++++++----
migration/colo.c | 16 ++++------------
monitor.c | 5 -----
4 files changed, 22 insertions(+), 26 deletions(-)
diff --git a/qapi/block-core.json b/qapi/block-core.json
index bb11815608..6f897cf157 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -2232,8 +2232,10 @@
'dmg', 'file', 'ftp', 'ftps', 'gluster', 'host_cdrom',
'host_device', 'http', 'https', 'iscsi', 'luks', 'nbd', 'nfs',
'null-aio', 'null-co', 'parallels', 'qcow', 'qcow2', 'qed',
- 'quorum', 'raw', 'rbd', 'replication', 'sheepdog', 'ssh',
- 'throttle', 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat', 'vxhs' ] }
+ 'quorum', 'raw', 'rbd',
+ { 'name': 'replication', 'if': 'defined(CONFIG_REPLICATION)' },
+ 'sheepdog', 'ssh', 'throttle',
+ 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat', 'vxhs' ] }
##
# @BlockdevOptionsFile:
@@ -2855,7 +2857,8 @@
#
# Since: 2.9
##
-{ 'enum' : 'ReplicationMode', 'data' : [ 'primary', 'secondary' ] }
+{ 'enum' : 'ReplicationMode', 'data' : [ 'primary', 'secondary' ],
+ 'if': 'defined(CONFIG_REPLICATION)' }
##
# @BlockdevOptionsReplication:
@@ -2873,7 +2876,8 @@
{ 'struct': 'BlockdevOptionsReplication',
'base': 'BlockdevOptionsGenericFormat',
'data': { 'mode': 'ReplicationMode',
- '*top-id': 'str' } }
+ '*top-id': 'str' },
+ 'if': 'defined(CONFIG_REPLICATION)' }
##
# @NFSTransport:
@@ -3168,7 +3172,8 @@
'quorum': 'BlockdevOptionsQuorum',
'raw': 'BlockdevOptionsRaw',
'rbd': 'BlockdevOptionsRbd',
- 'replication':'BlockdevOptionsReplication',
+ 'replication': { 'type': 'BlockdevOptionsReplication',
+ 'if': 'defined(CONFIG_REPLICATION)' },
'sheepdog': 'BlockdevOptionsSheepdog',
'ssh': 'BlockdevOptionsSsh',
'throttle': 'BlockdevOptionsThrottle',
diff --git a/qapi/migration.json b/qapi/migration.json
index ee2b3b8733..44d2ef9c94 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -1034,7 +1034,8 @@
# Since: 2.9
##
{ 'command': 'xen-set-replication',
- 'data': { 'enable': 'bool', 'primary': 'bool', '*failover' : 'bool' } }
+ 'data': { 'enable': 'bool', 'primary': 'bool', '*failover' : 'bool' },
+ 'if': 'defined(CONFIG_REPLICATION)' }
##
# @ReplicationStatus:
@@ -1049,7 +1050,8 @@
# Since: 2.9
##
{ 'struct': 'ReplicationStatus',
- 'data': { 'error': 'bool', '*desc': 'str' } }
+ 'data': { 'error': 'bool', '*desc': 'str' },
+ 'if': 'defined(CONFIG_REPLICATION)' }
##
# @query-xen-replication-status:
@@ -1066,7 +1068,8 @@
# Since: 2.9
##
{ 'command': 'query-xen-replication-status',
- 'returns': 'ReplicationStatus' }
+ 'returns': 'ReplicationStatus',
+ 'if': 'defined(CONFIG_REPLICATION)' }
##
# @xen-colo-do-checkpoint:
@@ -1082,4 +1085,5 @@
#
# Since: 2.9
##
-{ 'command': 'xen-colo-do-checkpoint' }
+{ 'command': 'xen-colo-do-checkpoint',
+ 'if': 'defined(CONFIG_REPLICATION)' }
diff --git a/migration/colo.c b/migration/colo.c
index dee3aa8bf7..010c9e02e8 100644
--- a/migration/colo.c
+++ b/migration/colo.c
@@ -22,7 +22,9 @@
#include "trace.h"
#include "qemu/error-report.h"
#include "migration/failover.h"
+#ifdef CONFIG_REPLICATION
#include "replication.h"
+#endif
#include "qmp-commands.h"
static bool vmstate_loading;
@@ -147,11 +149,11 @@ void colo_do_failover(MigrationState *s)
}
}
+#ifdef CONFIG_REPLICATION
void qmp_xen_set_replication(bool enable, bool primary,
bool has_failover, bool failover,
Error **errp)
{
-#ifdef CONFIG_REPLICATION
ReplicationMode mode = primary ?
REPLICATION_MODE_PRIMARY :
REPLICATION_MODE_SECONDARY;
@@ -170,14 +172,10 @@ void qmp_xen_set_replication(bool enable, bool primary,
}
replication_stop_all(failover, failover ? NULL : errp);
}
-#else
- abort();
-#endif
}
ReplicationStatus *qmp_query_xen_replication_status(Error **errp)
{
-#ifdef CONFIG_REPLICATION
Error *err = NULL;
ReplicationStatus *s = g_new0(ReplicationStatus, 1);
@@ -192,19 +190,13 @@ ReplicationStatus *qmp_query_xen_replication_status(Error **errp)
error_free(err);
return s;
-#else
- abort();
-#endif
}
void qmp_xen_colo_do_checkpoint(Error **errp)
{
-#ifdef CONFIG_REPLICATION
replication_do_checkpoint_all(errp);
-#else
- abort();
-#endif
}
+#endif
static void colo_send_message(QEMUFile *f, COLOMessage msg,
Error **errp)
diff --git a/monitor.c b/monitor.c
index 135a1e0821..b5ddcf8c67 100644
--- a/monitor.c
+++ b/monitor.c
@@ -970,11 +970,6 @@ static void qmp_query_qmp_schema(QDict *qdict, QObject **ret_data,
*/
static void qmp_unregister_commands_hack(void)
{
-#ifndef CONFIG_REPLICATION
- qmp_unregister_command(&qmp_commands, "xen-set-replication");
- qmp_unregister_command(&qmp_commands, "query-xen-replication-status");
- qmp_unregister_command(&qmp_commands, "xen-colo-do-checkpoint");
-#endif
#ifndef TARGET_I386
qmp_unregister_command(&qmp_commands, "rtc-reset-reinjection");
#endif
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 39/50] qapi-commands: don't initialize command list in qmp_init_marshall()
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (37 preceding siblings ...)
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 38/50] qapi: add conditions to REPLICATION type/commands " Marc-André Lureau
@ 2017-09-11 11:06 ` Marc-André Lureau
2017-12-13 16:23 ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 40/50] qapi: add -i/--include filename.h Marc-André Lureau
` (12 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:06 UTC (permalink / raw)
To: qemu-devel
Cc: armbru, Marc-André Lureau, Dr. David Alan Gilbert, Michael Roth
This will let the caller add several list of commands.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi-commands.py | 2 --
monitor.c | 1 +
qga/main.c | 1 +
tests/test-qmp-commands.c | 1 +
4 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index 8af8d913b9..7455d2b8bb 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -211,8 +211,6 @@ def gen_registry(registry):
void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds)
{
- QTAILQ_INIT(cmds);
-
''',
c_prefix=c_name(prefix, protect=False))
ret += registry
diff --git a/monitor.c b/monitor.c
index b5ddcf8c67..bf8a7685bf 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1001,6 +1001,7 @@ void monitor_init_qmp_commands(void)
* "qmp_capabilities", to enforce capability negotiation
*/
+ QTAILQ_INIT(&qmp_commands);
qmp_init_marshal(&qmp_commands);
qmp_register_command(&qmp_commands, "query-qmp-schema",
diff --git a/qga/main.c b/qga/main.c
index 62a62755bd..b949b1ccb0 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -1360,6 +1360,7 @@ int main(int argc, char **argv)
config->log_level = G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL;
+ QTAILQ_INIT(&ga_commands);
qga_qmp_init_marshal(&ga_commands);
init_dfl_pathnames();
diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c
index ad7b6e4e1d..28ce88e012 100644
--- a/tests/test-qmp-commands.c
+++ b/tests/test-qmp-commands.c
@@ -283,6 +283,7 @@ int main(int argc, char **argv)
g_test_add_func("/0.15/dealloc_types", test_dealloc_types);
g_test_add_func("/0.15/dealloc_partial", test_dealloc_partial);
+ QTAILQ_INIT(&qmp_commands);
test_qmp_init_marshal(&qmp_commands);
g_test_run();
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 40/50] qapi: add -i/--include filename.h
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (38 preceding siblings ...)
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 39/50] qapi-commands: don't initialize command list in qmp_init_marshall() Marc-André Lureau
@ 2017-09-11 11:06 ` Marc-André Lureau
2017-12-14 13:50 ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 41/50] qapi: add a 'unit' pragma Marc-André Lureau
` (11 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:06 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
Add a new option to add user-specified #include lines in the generated
headers. This will help to split a schema, where one generated header
will depend on another.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi.py | 13 +++++++++----
scripts/qapi-commands.py | 7 +++++--
scripts/qapi-event.py | 6 ++++--
scripts/qapi-introspect.py | 5 +++--
scripts/qapi-types.py | 6 ++++--
scripts/qapi-visit.py | 5 +++--
6 files changed, 28 insertions(+), 14 deletions(-)
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 19e48bd4d2..eb4ffdc06d 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -2096,9 +2096,9 @@ def parse_command_line(extra_options='', extra_long_options=[]):
try:
opts, args = getopt.gnu_getopt(sys.argv[1:],
- 'chp:o:' + extra_options,
- ['source', 'header', 'prefix=',
- 'output-dir='] + extra_long_options)
+ 'chp:o:i:' + extra_options,
+ ['source', 'header', 'prefix=', 'output-dir=',
+ 'include='] + extra_long_options)
except getopt.GetoptError as err:
print >>sys.stderr, "%s: %s" % (sys.argv[0], str(err))
sys.exit(1)
@@ -2107,6 +2107,7 @@ def parse_command_line(extra_options='', extra_long_options=[]):
prefix = ''
do_c = False
do_h = False
+ includes = []
extra_opts = []
for oa in opts:
@@ -2125,6 +2126,8 @@ def parse_command_line(extra_options='', extra_long_options=[]):
do_c = True
elif o in ('-h', '--header'):
do_h = True
+ elif o in ('-i', '--include'):
+ includes.append(a)
else:
extra_opts.append(oa)
@@ -2137,7 +2140,9 @@ def parse_command_line(extra_options='', extra_long_options=[]):
sys.exit(1)
fname = args[0]
- return (fname, output_dir, do_c, do_h, prefix, extra_opts)
+ includes = "\n".join(['#include "%s"' % inc for inc in includes])
+
+ return (fname, output_dir, do_c, do_h, prefix, includes, extra_opts)
#
# Generate output files with boilerplate
diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index 7455d2b8bb..4841f4d9a1 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -253,7 +253,8 @@ class QAPISchemaGenCommandVisitor(QAPISchemaVisitor):
self._regy += gen_register_command(name, success_response)
-(input_file, output_dir, do_c, do_h, prefix, opts) = parse_command_line()
+(input_file, output_dir, do_c, do_h, prefix, includes, opts) = \
+ parse_command_line()
c_comment = '''
/*
@@ -305,6 +306,7 @@ fdef.write(mcgen('''
prefix=prefix))
fdecl.write(mcgen('''
+%(includes)s
#include "%(prefix)sqapi-types.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/dispatch.h"
@@ -312,7 +314,8 @@ fdecl.write(mcgen('''
void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds);
''',
- prefix=prefix, c_prefix=c_name(prefix, protect=False)))
+ includes=includes, prefix=prefix,
+ c_prefix=c_name(prefix, protect=False)))
schema = QAPISchema(input_file)
gen = QAPISchemaGenCommandVisitor()
diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py
index 60c6f7030d..0aba866dc8 100644
--- a/scripts/qapi-event.py
+++ b/scripts/qapi-event.py
@@ -171,7 +171,8 @@ class QAPISchemaGenEventVisitor(QAPISchemaVisitor):
self._event_names.append(QAPISchemaMember(name, ifcond))
-(input_file, output_dir, do_c, do_h, prefix, dummy) = parse_command_line()
+(input_file, output_dir, do_c, do_h, prefix, includes, dummy) = \
+ parse_command_line()
c_comment = '''
/*
@@ -218,13 +219,14 @@ fdef.write(mcgen('''
prefix=prefix))
fdecl.write(mcgen('''
+%(includes)s
#include "qapi/error.h"
#include "qapi/util.h"
#include "qapi/qmp/qdict.h"
#include "%(prefix)sqapi-types.h"
''',
- prefix=prefix))
+ includes=includes, prefix=prefix))
event_enum_name = c_name(prefix + 'QAPIEvent', protect=False)
diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
index d6194ff702..f9abd83490 100644
--- a/scripts/qapi-introspect.py
+++ b/scripts/qapi-introspect.py
@@ -192,7 +192,7 @@ const QLitObject %(c_name)s = %(c_string)s;
# We normally mask them, because they're not QMP wire ABI
opt_unmask = False
-(input_file, output_dir, do_c, do_h, prefix, opts) = \
+(input_file, output_dir, do_c, do_h, prefix, includes, opts) = \
parse_command_line('u', ['unmask-non-abi-names'])
for o, a in opts:
@@ -235,10 +235,11 @@ fdef.write(mcgen('''
prefix=prefix))
fdecl.write(mcgen('''
+%(includes)s
#include "qemu/osdep.h"
#include "qapi/qmp/qlit.h"
-'''))
+''', includes=includes))
schema = QAPISchema(input_file)
gen = QAPISchemaGenIntrospectVisitor(opt_unmask)
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 312685c295..2b46a7e17f 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -266,7 +266,7 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
# QAPISchemaGenTypeVisitor.visit_end().
do_builtins = False
-(input_file, output_dir, do_c, do_h, prefix, opts) = \
+(input_file, output_dir, do_c, do_h, prefix, includes, opts) = \
parse_command_line('b', ['builtins'])
for o, a in opts:
@@ -317,7 +317,9 @@ fdef.write(mcgen('''
fdecl.write(mcgen('''
#include "qapi/util.h"
-'''))
+%(includes)s
+''',
+ includes=includes))
schema = QAPISchema(input_file)
gen = QAPISchemaGenTypeVisitor()
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 369e1f927d..1e173d3cd7 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -338,7 +338,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
# QAPISchemaGenVisitVisitor.visit_end().
do_builtins = False
-(input_file, output_dir, do_c, do_h, prefix, opts) = \
+(input_file, output_dir, do_c, do_h, prefix, includes, opts) = \
parse_command_line('b', ['builtins'])
for o, a in opts:
@@ -387,12 +387,13 @@ fdef.write(mcgen('''
prefix=prefix))
fdecl.write(mcgen('''
+%(includes)s
#include "qapi/visitor.h"
#include "qapi/qmp/qerror.h"
#include "%(prefix)sqapi-types.h"
''',
- prefix=prefix))
+ includes=includes, prefix=prefix))
schema = QAPISchema(input_file)
gen = QAPISchemaGenVisitVisitor()
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 41/50] qapi: add a 'unit' pragma
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (39 preceding siblings ...)
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 40/50] qapi: add -i/--include filename.h Marc-André Lureau
@ 2017-09-11 11:06 ` Marc-André Lureau
2017-12-14 13:54 ` Markus Armbruster
2017-12-14 16:08 ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 42/50] qapi: add a -u/--unit option to specify which unit to visit Marc-André Lureau
` (10 subsequent siblings)
51 siblings, 2 replies; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:06 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
Add a pragma that allows to tag the following expressions with a unit
name. By default, an expression has no unit name.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi.py | 9 ++++++++-
docs/devel/qapi-code-gen.txt | 3 +++
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/scripts/qapi.py b/scripts/qapi.py
index eb4ffdc06d..1d0defd638 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -279,10 +279,12 @@ class QAPISchemaParser(object):
self.docs = []
self.cur_doc = None
self.accept()
+ self.unit = None
while self.tok is not None:
info = {'file': fname, 'line': self.line,
- 'parent': self.incl_info}
+ 'parent': self.incl_info,
+ 'unit': self.unit}
if self.tok == '#':
self.reject_expr_doc()
self.cur_doc = self.get_doc(info)
@@ -371,6 +373,11 @@ class QAPISchemaParser(object):
"Pragma name-case-whitelist must be"
" a list of strings")
name_case_whitelist = value
+ elif name == 'unit':
+ if not isinstance(value, str):
+ raise QAPISemError(info,
+ "Pragma 'unit' must be string")
+ self.unit = value
else:
raise QAPISemError(info, "Unknown pragma '%s'" % name)
diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt
index 24fc6f74ee..37a27cd9d7 100644
--- a/docs/devel/qapi-code-gen.txt
+++ b/docs/devel/qapi-code-gen.txt
@@ -326,6 +326,9 @@ violate the rules on permitted return types. Default is none.
Pragma 'name-case-whitelist' takes a list of names that may violate
rules on use of upper- vs. lower-case letters. Default is none.
+Pragma 'unit' takes a string value. It will set the unit name for the
+following expressions in the schema. Most code generator can filter
+based on a unit name. Default is none.
=== Struct types ===
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 42/50] qapi: add a -u/--unit option to specify which unit to visit
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (40 preceding siblings ...)
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 41/50] qapi: add a 'unit' pragma Marc-André Lureau
@ 2017-09-11 11:06 ` Marc-André Lureau
2017-12-14 16:16 ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 43/50] build-sys: move qmp-introspect per target Marc-André Lureau
` (9 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:06 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
Allow to filter expressions based on unit name.
By default, only default units are processed (unspecified pragma).
'all' will include all units. Anything else will filter by unit name.
(add a FIXME to make implicit array types use the element type unit,
not the unit of the first expression using that array type. This isn't
necessary for now, and I am not sure how to best do it yet)
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi.py | 14 ++++++++++++--
scripts/qapi2texi.py | 1 +
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 1d0defd638..7778585819 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -47,6 +47,9 @@ returns_whitelist = []
# Whitelist of entities allowed to violate case conventions
name_case_whitelist = []
+# Unit to consider for the visit, 'all' for all units
+visit_unit = None
+
enum_types = {}
struct_types = {}
union_types = {}
@@ -1796,6 +1799,10 @@ class QAPISchema(object):
def visit(self, visitor):
visitor.visit_begin(self)
for (name, entity) in sorted(self._entity_dict.items()):
+ # FIXME: implicit array types should use element type unit
+ unit = entity.info and entity.info.get('unit')
+ if visit_unit != 'all' and visit_unit != unit:
+ continue
if visitor.visit_needed(entity):
entity.visit(visitor)
visitor.visit_end()
@@ -2103,13 +2110,14 @@ def parse_command_line(extra_options='', extra_long_options=[]):
try:
opts, args = getopt.gnu_getopt(sys.argv[1:],
- 'chp:o:i:' + extra_options,
+ 'chp:o:u:i:' + extra_options,
['source', 'header', 'prefix=', 'output-dir=',
- 'include='] + extra_long_options)
+ 'unit=', 'include='] + extra_long_options)
except getopt.GetoptError as err:
print >>sys.stderr, "%s: %s" % (sys.argv[0], str(err))
sys.exit(1)
+ global visit_unit
output_dir = ''
prefix = ''
do_c = False
@@ -2129,6 +2137,8 @@ def parse_command_line(extra_options='', extra_long_options=[]):
prefix = a
elif o in ('-o', '--output-dir'):
output_dir = a + '/'
+ elif o in ('-u', '--unit'):
+ visit_unit = a
elif o in ('-c', '--source'):
do_c = True
elif o in ('-h', '--header'):
diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py
index 4e7b1cda87..6c856d4cb7 100755
--- a/scripts/qapi2texi.py
+++ b/scripts/qapi2texi.py
@@ -293,6 +293,7 @@ def main(argv):
print >>sys.stderr, "%s: need exactly 1 argument: SCHEMA" % argv[0]
sys.exit(1)
+ qapi.visit_unit = 'all'
schema = qapi.QAPISchema(argv[1])
if not qapi.doc_required:
print >>sys.stderr, ("%s: need pragma 'doc-required' "
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 43/50] build-sys: move qmp-introspect per target
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (41 preceding siblings ...)
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 42/50] qapi: add a -u/--unit option to specify which unit to visit Marc-André Lureau
@ 2017-09-11 11:06 ` Marc-André Lureau
2017-12-14 16:30 ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 44/50] build-sys: add a target schema Marc-André Lureau
` (8 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:06 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Michael Roth
The following patches are going to introduce per-target #ifdef, and
but the introspection data is generated only once, and must thus be
built with the target.
Drop "do_test_visitor_in_qmp_introspect(&&qmp_schema_qlit)" since it
is no longer in a common object, and covered by "query-qmp-schema
test" instead.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
tests/test-qobject-input-visitor.c | 1 -
Makefile.objs | 3 +--
Makefile.target | 2 ++
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/tests/test-qobject-input-visitor.c b/tests/test-qobject-input-visitor.c
index 7c1d10e274..ad4c99a4c7 100644
--- a/tests/test-qobject-input-visitor.c
+++ b/tests/test-qobject-input-visitor.c
@@ -1267,7 +1267,6 @@ static void test_visitor_in_qmp_introspect(TestInputVisitorData *data,
const void *unused)
{
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/Makefile.objs b/Makefile.objs
index 24a4ea08b8..f8ba6228ca 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -2,7 +2,7 @@
# Common libraries for tools and emulators
stub-obj-y = stubs/ crypto/
util-obj-y = util/ qobject/ qapi/
-util-obj-y += qmp-introspect.o qapi-types.o qapi-visit.o qapi-event.o
+util-obj-y += qapi-types.o qapi-visit.o qapi-event.o
chardev-obj-y = chardev/
@@ -77,7 +77,6 @@ common-obj-$(CONFIG_FDT) += device_tree.o
# qapi
common-obj-y += qmp-marshal.o
-common-obj-y += qmp-introspect.o
common-obj-y += qmp.o hmp.o
endif
diff --git a/Makefile.target b/Makefile.target
index 7f42c45db8..0d28ed1df0 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -157,6 +157,8 @@ endif
GENERATED_FILES += hmp-commands.h hmp-commands-info.h
+obj-y += qmp-introspect.o
+
endif # CONFIG_SOFTMMU
# Workaround for http://gcc.gnu.org/PR55489, see configure.
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 44/50] build-sys: add a target schema
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (42 preceding siblings ...)
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 43/50] build-sys: move qmp-introspect per target Marc-André Lureau
@ 2017-09-11 11:06 ` Marc-André Lureau
2017-12-14 16:34 ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 45/50] qapi: make rtc-reset-reinjection depend on TARGET_I386 Marc-André Lureau
` (7 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:06 UTC (permalink / raw)
To: qemu-devel
Cc: armbru, Marc-André Lureau, Dr. David Alan Gilbert, Eric Blake
This schema is going to contain target-specific commands/events &
types, that can be conditionnally guarded with poisoned defines. To
filter it out by default, set the unit name to 'target'.
And new rules to compile this unit generated files per-target.
Use the "-u all" options for the introspection schema, since it is
generated as a single file and must contain all definitions.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qapi-schema.json | 1 +
qapi/target.json | 3 +++
monitor.c | 2 ++
Makefile | 29 ++++++++++++++++++++++++++++-
Makefile.target | 2 ++
5 files changed, 36 insertions(+), 1 deletion(-)
create mode 100644 qapi/target.json
diff --git a/qapi-schema.json b/qapi-schema.json
index f3af2cb851..42b6aebddb 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -92,6 +92,7 @@
{ 'include': 'qapi/transaction.json' }
{ 'include': 'qapi/trace.json' }
{ 'include': 'qapi/introspect.json' }
+{ 'include': 'qapi/target.json' }
##
# = Miscellanea
diff --git a/qapi/target.json b/qapi/target.json
new file mode 100644
index 0000000000..e9644f52c2
--- /dev/null
+++ b/qapi/target.json
@@ -0,0 +1,3 @@
+# -*- Mode: Python -*-
+
+{ 'pragma': { 'unit': 'target' } }
diff --git a/monitor.c b/monitor.c
index bf8a7685bf..af4eaeca5e 100644
--- a/monitor.c
+++ b/monitor.c
@@ -68,6 +68,7 @@
#include "exec/exec-all.h"
#include "qemu/log.h"
#include "qmp-commands.h"
+#include "target-qmp-commands.h"
#include "hmp.h"
#include "qemu/thread.h"
#include "block/qapi.h"
@@ -1003,6 +1004,7 @@ void monitor_init_qmp_commands(void)
QTAILQ_INIT(&qmp_commands);
qmp_init_marshal(&qmp_commands);
+ target_qmp_init_marshal(&qmp_commands);
qmp_register_command(&qmp_commands, "query-qmp-schema",
qmp_query_qmp_schema,
diff --git a/Makefile b/Makefile
index 337a1f6f9b..7356b4e7b7 100644
--- a/Makefile
+++ b/Makefile
@@ -54,6 +54,8 @@ include $(SRC_PATH)/rules.mak
GENERATED_FILES = qemu-version.h config-host.h qemu-options.def
GENERATED_FILES += qmp-commands.h qapi-types.h qapi-visit.h qapi-event.h
GENERATED_FILES += qmp-marshal.c qapi-types.c qapi-visit.c qapi-event.c
+GENERATED_FILES += target-qmp-commands.h target-qapi-types.h target-qapi-visit.h target-qapi-event.h
+GENERATED_FILES += target-qmp-marshal.c target-qapi-types.c target-qapi-visit.c target-qapi-event.c
GENERATED_FILES += qmp-introspect.h
GENERATED_FILES += qmp-introspect.c
@@ -418,6 +420,7 @@ qapi-modules = $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi/common.json \
$(SRC_PATH)/qapi/rocker.json \
$(SRC_PATH)/qapi/run-state.json \
$(SRC_PATH)/qapi/sockets.json \
+ $(SRC_PATH)/qapi/target.json \
$(SRC_PATH)/qapi/tpm.json \
$(SRC_PATH)/qapi/trace.json \
$(SRC_PATH)/qapi/transaction.json \
@@ -443,10 +446,34 @@ $(qapi-modules) $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py \
$(gen-out-type) -o "." $<, \
"GEN","$@")
+
+target-qapi-types.c target-qapi-types.h :\
+$(qapi-modules) $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
+ $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py \
+ -i qapi-types.h \
+ $(gen-out-type) -p target- -u target $<, \
+ "GEN","$@")
+target-qapi-visit.c target-qapi-visit.h :\
+$(qapi-modules) $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py)
+ $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py \
+ -i qapi-visit.h \
+ $(gen-out-type) -p target- -u target $<, \
+ "GEN","$@")
+target-qapi-event.c target-qapi-event.h :\
+$(qapi-modules) $(SRC_PATH)/scripts/qapi-event.py $(qapi-py)
+ $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-event.py \
+ $(gen-out-type) -p target- -u target $<, \
+ "GEN","$@")
+target-qmp-commands.h target-qmp-marshal.c :\
+$(qapi-modules) $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
+ $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py \
+ $(gen-out-type) -p target- -u target $<, \
+ "GEN","$@")
+
qmp-introspect.h qmp-introspect.c :\
$(qapi-modules) $(SRC_PATH)/scripts/qapi-introspect.py $(qapi-py)
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-introspect.py \
- $(gen-out-type) -o "." $<, \
+ $(gen-out-type) -o "." -u all $<, \
"GEN","$@")
QGALIB_GEN=$(addprefix qga/qapi-generated/, qga-qapi-types.h qga-qapi-visit.h qga-qmp-commands.h)
diff --git a/Makefile.target b/Makefile.target
index 0d28ed1df0..e44a3847d3 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -157,6 +157,8 @@ endif
GENERATED_FILES += hmp-commands.h hmp-commands-info.h
+obj-y += target-qapi-types.o target-qapi-visit.o
+obj-y += target-qapi-event.o target-qmp-marshal.o
obj-y += qmp-introspect.o
endif # CONFIG_SOFTMMU
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 45/50] qapi: make rtc-reset-reinjection depend on TARGET_I386
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (43 preceding siblings ...)
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 44/50] build-sys: add a target schema Marc-André Lureau
@ 2017-09-11 11:06 ` Marc-André Lureau
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 46/50] qapi: make s390 commands depend on TARGET_S390X Marc-André Lureau
` (6 subsequent siblings)
51 siblings, 0 replies; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:06 UTC (permalink / raw)
To: qemu-devel
Cc: armbru, Marc-André Lureau, Michael S. Tsirkin,
Paolo Bonzini, Dr. David Alan Gilbert, Eric Blake
Move rtc-reset-reinjection in target.json and make it conditional on
TARGET_I386.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qapi-schema.json | 18 ------------------
qapi/target.json | 19 +++++++++++++++++++
hw/timer/mc146818rtc.c | 2 +-
monitor.c | 10 ----------
4 files changed, 20 insertions(+), 29 deletions(-)
diff --git a/qapi-schema.json b/qapi-schema.json
index 42b6aebddb..5b689c71ad 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2919,24 +2919,6 @@
{ 'event': 'ACPI_DEVICE_OST',
'data': { 'info': 'ACPIOSTInfo' } }
-##
-# @rtc-reset-reinjection:
-#
-# This command will reset the RTC interrupt reinjection backlog.
-# Can be used if another mechanism to synchronize guest time
-# is in effect, for example QEMU guest agent's guest-set-time
-# command.
-#
-# Since: 2.1
-#
-# Example:
-#
-# -> { "execute": "rtc-reset-reinjection" }
-# <- { "return": {} }
-#
-##
-{ 'command': 'rtc-reset-reinjection' }
-
##
# @RTC_CHANGE:
#
diff --git a/qapi/target.json b/qapi/target.json
index e9644f52c2..a764377ebf 100644
--- a/qapi/target.json
+++ b/qapi/target.json
@@ -1,3 +1,22 @@
# -*- Mode: Python -*-
{ 'pragma': { 'unit': 'target' } }
+
+##
+# @rtc-reset-reinjection:
+#
+# This command will reset the RTC interrupt reinjection backlog.
+# Can be used if another mechanism to synchronize guest time
+# is in effect, for example QEMU guest agent's guest-set-time
+# command.
+#
+# Since: 2.1
+#
+# Example:
+#
+# -> { "execute": "rtc-reset-reinjection" }
+# <- { "return": {} }
+#
+##
+{ 'command': 'rtc-reset-reinjection',
+ 'if': 'defined(TARGET_I386)' }
diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c
index 82843ed03f..3a5ddd074a 100644
--- a/hw/timer/mc146818rtc.c
+++ b/hw/timer/mc146818rtc.c
@@ -31,7 +31,7 @@
#include "hw/timer/mc146818rtc.h"
#include "qapi/visitor.h"
#include "qapi-event.h"
-#include "qmp-commands.h"
+#include "target-qmp-commands.h"
#ifdef TARGET_I386
#include "hw/i386/apic.h"
diff --git a/monitor.c b/monitor.c
index af4eaeca5e..ff93d9a9a9 100644
--- a/monitor.c
+++ b/monitor.c
@@ -971,9 +971,6 @@ static void qmp_query_qmp_schema(QDict *qdict, QObject **ret_data,
*/
static void qmp_unregister_commands_hack(void)
{
-#ifndef TARGET_I386
- qmp_unregister_command(&qmp_commands, "rtc-reset-reinjection");
-#endif
#ifndef TARGET_S390X
qmp_unregister_command(&qmp_commands, "dump-skeys");
#endif
@@ -4155,13 +4152,6 @@ QemuOptsList qemu_mon_opts = {
},
};
-#ifndef TARGET_I386
-void qmp_rtc_reset_reinjection(Error **errp)
-{
- error_setg(errp, QERR_FEATURE_DISABLED, "rtc-reset-reinjection");
-}
-#endif
-
#ifndef TARGET_S390X
void qmp_dump_skeys(const char *filename, Error **errp)
{
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 46/50] qapi: make s390 commands depend on TARGET_S390X
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (44 preceding siblings ...)
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 45/50] qapi: make rtc-reset-reinjection depend on TARGET_I386 Marc-André Lureau
@ 2017-09-11 11:06 ` Marc-André Lureau
2017-09-13 7:45 ` Cornelia Huck
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 47/50] target.json: add a note about query-cpu* not being s390x-specific Marc-André Lureau
` (5 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:06 UTC (permalink / raw)
To: qemu-devel
Cc: armbru, Marc-André Lureau, Richard Henderson,
Alexander Graf, Cornelia Huck, Christian Borntraeger,
Dr. David Alan Gilbert, Eric Blake, Paolo Bonzini
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qapi-schema.json | 101 -------------------------------
qapi/target.json | 104 ++++++++++++++++++++++++++++++++
include/sysemu/arch_init.h | 7 ---
hw/s390x/s390-skeys.c | 2 +-
monitor.c | 14 -----
qmp.c | 14 -----
stubs/arch-query-cpu-model-baseline.c | 12 ----
stubs/arch-query-cpu-model-comparison.c | 12 ----
target/s390x/cpu_models.c | 5 +-
stubs/Makefile.objs | 2 -
10 files changed, 108 insertions(+), 165 deletions(-)
delete mode 100644 stubs/arch-query-cpu-model-baseline.c
delete mode 100644 stubs/arch-query-cpu-model-comparison.c
diff --git a/qapi-schema.json b/qapi-schema.json
index 5b689c71ad..b4a5f9abc5 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1771,27 +1771,6 @@
{ 'command': 'query-dump-guest-memory-capability',
'returns': 'DumpGuestMemoryCapability' }
-##
-# @dump-skeys:
-#
-# Dump guest's storage keys
-#
-# @filename: the path to the file to dump to
-#
-# This command is only supported on s390 architecture.
-#
-# Since: 2.5
-#
-# Example:
-#
-# -> { "execute": "dump-skeys",
-# "arguments": { "filename": "/tmp/skeys" } }
-# <- { "return": {} }
-#
-##
-{ 'command': 'dump-skeys',
- 'data': { 'filename': 'str' } }
-
##
# @object-add:
#
@@ -2126,46 +2105,6 @@
}
}
-##
-# @query-cpu-model-comparison:
-#
-# Compares two CPU models, returning how they compare in a specific
-# configuration. The results indicates how both models compare regarding
-# runnability. This result can be used by tooling to make decisions if a
-# certain CPU model will run in a certain configuration or if a compatible
-# CPU model has to be created by baselining.
-#
-# Usually, a CPU model is compared against the maximum possible CPU model
-# of a certain configuration (e.g. the "host" model for KVM). If that CPU
-# model is identical or a subset, it will run in that configuration.
-#
-# The result returned by this command may be affected by:
-#
-# * QEMU version: CPU models may look different depending on the QEMU version.
-# (Except for CPU models reported as "static" in query-cpu-definitions.)
-# * machine-type: CPU model may look different depending on the machine-type.
-# (Except for CPU models reported as "static" in query-cpu-definitions.)
-# * machine options (including accelerator): in some architectures, CPU models
-# may look different depending on machine and accelerator options. (Except for
-# CPU models reported as "static" in query-cpu-definitions.)
-# * "-cpu" arguments and global properties: arguments to the -cpu option and
-# global properties may affect expansion of CPU models. Using
-# query-cpu-model-expansion while using these is not advised.
-#
-# Some architectures may not support comparing CPU models. s390x supports
-# comparing CPU models.
-#
-# Returns: a CpuModelBaselineInfo. Returns an error if comparing CPU models is
-# not supported, if a model cannot be used, if a model contains
-# an unknown cpu definition name, unknown properties or properties
-# with wrong types.
-#
-# Since: 2.8.0
-##
-{ 'command': 'query-cpu-model-comparison',
- 'data': { 'modela': 'CpuModelInfo', 'modelb': 'CpuModelInfo' },
- 'returns': 'CpuModelCompareInfo' }
-
##
# @CpuModelBaselineInfo:
#
@@ -2178,46 +2117,6 @@
{ 'struct': 'CpuModelBaselineInfo',
'data': { 'model': 'CpuModelInfo' } }
-##
-# @query-cpu-model-baseline:
-#
-# Baseline two CPU models, creating a compatible third model. The created
-# model will always be a static, migration-safe CPU model (see "static"
-# CPU model expansion for details).
-#
-# This interface can be used by tooling to create a compatible CPU model out
-# two CPU models. The created CPU model will be identical to or a subset of
-# both CPU models when comparing them. Therefore, the created CPU model is
-# guaranteed to run where the given CPU models run.
-#
-# The result returned by this command may be affected by:
-#
-# * QEMU version: CPU models may look different depending on the QEMU version.
-# (Except for CPU models reported as "static" in query-cpu-definitions.)
-# * machine-type: CPU model may look different depending on the machine-type.
-# (Except for CPU models reported as "static" in query-cpu-definitions.)
-# * machine options (including accelerator): in some architectures, CPU models
-# may look different depending on machine and accelerator options. (Except for
-# CPU models reported as "static" in query-cpu-definitions.)
-# * "-cpu" arguments and global properties: arguments to the -cpu option and
-# global properties may affect expansion of CPU models. Using
-# query-cpu-model-expansion while using these is not advised.
-#
-# Some architectures may not support baselining CPU models. s390x supports
-# baselining CPU models.
-#
-# Returns: a CpuModelBaselineInfo. Returns an error if baselining CPU models is
-# not supported, if a model cannot be used, if a model contains
-# an unknown cpu definition name, unknown properties or properties
-# with wrong types.
-#
-# Since: 2.8.0
-##
-{ 'command': 'query-cpu-model-baseline',
- 'data': { 'modela': 'CpuModelInfo',
- 'modelb': 'CpuModelInfo' },
- 'returns': 'CpuModelBaselineInfo' }
-
##
# @AddfdInfo:
#
diff --git a/qapi/target.json b/qapi/target.json
index a764377ebf..3b73a9202f 100644
--- a/qapi/target.json
+++ b/qapi/target.json
@@ -20,3 +20,107 @@
##
{ 'command': 'rtc-reset-reinjection',
'if': 'defined(TARGET_I386)' }
+
+##
+# @dump-skeys:
+#
+# Dump guest's storage keys
+#
+# @filename: the path to the file to dump to
+#
+# This command is only supported on s390 architecture.
+#
+# Since: 2.5
+#
+# Example:
+#
+# -> { "execute": "dump-skeys",
+# "arguments": { "filename": "/tmp/skeys" } }
+# <- { "return": {} }
+#
+##
+{ 'command': 'dump-skeys',
+ 'data': { 'filename': 'str' },
+ 'if': 'defined(TARGET_S390X)' }
+
+##
+# @query-cpu-model-comparison:
+#
+# Compares two CPU models, returning how they compare in a specific
+# configuration. The results indicates how both models compare regarding
+# runnability. This result can be used by tooling to make decisions if a
+# certain CPU model will run in a certain configuration or if a compatible
+# CPU model has to be created by baselining.
+#
+# Usually, a CPU model is compared against the maximum possible CPU model
+# of a certain configuration (e.g. the "host" model for KVM). If that CPU
+# model is identical or a subset, it will run in that configuration.
+#
+# The result returned by this command may be affected by:
+#
+# * QEMU version: CPU models may look different depending on the QEMU version.
+# (Except for CPU models reported as "static" in query-cpu-definitions.)
+# * machine-type: CPU model may look different depending on the machine-type.
+# (Except for CPU models reported as "static" in query-cpu-definitions.)
+# * machine options (including accelerator): in some architectures, CPU models
+# may look different depending on machine and accelerator options. (Except for
+# CPU models reported as "static" in query-cpu-definitions.)
+# * "-cpu" arguments and global properties: arguments to the -cpu option and
+# global properties may affect expansion of CPU models. Using
+# query-cpu-model-expansion while using these is not advised.
+#
+# Some architectures may not support comparing CPU models. s390x supports
+# comparing CPU models.
+#
+# Returns: a CpuModelBaselineInfo. Returns an error if comparing CPU models is
+# not supported, if a model cannot be used, if a model contains
+# an unknown cpu definition name, unknown properties or properties
+# with wrong types.
+#
+# Since: 2.8.0
+##
+{ 'command': 'query-cpu-model-comparison',
+ 'data': { 'modela': 'CpuModelInfo', 'modelb': 'CpuModelInfo' },
+ 'returns': 'CpuModelCompareInfo',
+ 'if': 'defined(TARGET_S390X)' }
+
+##
+# @query-cpu-model-baseline:
+#
+# Baseline two CPU models, creating a compatible third model. The created
+# model will always be a static, migration-safe CPU model (see "static"
+# CPU model expansion for details).
+#
+# This interface can be used by tooling to create a compatible CPU model out
+# two CPU models. The created CPU model will be identical to or a subset of
+# both CPU models when comparing them. Therefore, the created CPU model is
+# guaranteed to run where the given CPU models run.
+#
+# The result returned by this command may be affected by:
+#
+# * QEMU version: CPU models may look different depending on the QEMU version.
+# (Except for CPU models reported as "static" in query-cpu-definitions.)
+# * machine-type: CPU model may look different depending on the machine-type.
+# (Except for CPU models reported as "static" in query-cpu-definitions.)
+# * machine options (including accelerator): in some architectures, CPU models
+# may look different depending on machine and accelerator options. (Except for
+# CPU models reported as "static" in query-cpu-definitions.)
+# * "-cpu" arguments and global properties: arguments to the -cpu option and
+# global properties may affect expansion of CPU models. Using
+# query-cpu-model-expansion while using these is not advised.
+#
+# Some architectures may not support baselining CPU models. s390x supports
+# baselining CPU models.
+#
+# Returns: a CpuModelBaselineInfo. Returns an error if baselining CPU models is
+# not supported, if a model cannot be used, if a model contains
+# an unknown cpu definition name, unknown properties or properties
+# with wrong types.
+#
+# Since: 2.8.0
+##
+{ 'command': 'query-cpu-model-baseline',
+ 'data': { 'modela': 'CpuModelInfo',
+ 'modelb': 'CpuModelInfo' },
+ 'returns': 'CpuModelBaselineInfo',
+ 'if': 'defined(TARGET_S390X)' }
diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index 8751c468ed..f193f5189b 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -35,11 +35,4 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp);
CpuModelExpansionInfo *arch_query_cpu_model_expansion(CpuModelExpansionType type,
CpuModelInfo *mode,
Error **errp);
-CpuModelCompareInfo *arch_query_cpu_model_comparison(CpuModelInfo *modela,
- CpuModelInfo *modelb,
- Error **errp);
-CpuModelBaselineInfo *arch_query_cpu_model_baseline(CpuModelInfo *modela,
- CpuModelInfo *modelb,
- Error **errp);
-
#endif
diff --git a/hw/s390x/s390-skeys.c b/hw/s390x/s390-skeys.c
index 53ad5d38d4..5af2f89994 100644
--- a/hw/s390x/s390-skeys.c
+++ b/hw/s390x/s390-skeys.c
@@ -11,7 +11,7 @@
#include "qemu/osdep.h"
#include "hw/boards.h"
-#include "qmp-commands.h"
+#include "target-qmp-commands.h"
#include "hw/s390x/storage-keys.h"
#include "qemu/error-report.h"
#include "sysemu/kvm.h"
diff --git a/monitor.c b/monitor.c
index ff93d9a9a9..622ba3b819 100644
--- a/monitor.c
+++ b/monitor.c
@@ -971,19 +971,12 @@ static void qmp_query_qmp_schema(QDict *qdict, QObject **ret_data,
*/
static void qmp_unregister_commands_hack(void)
{
-#ifndef TARGET_S390X
- qmp_unregister_command(&qmp_commands, "dump-skeys");
-#endif
#ifndef TARGET_ARM
qmp_unregister_command(&qmp_commands, "query-gic-capabilities");
#endif
#if !defined(TARGET_S390X) && !defined(TARGET_I386)
qmp_unregister_command(&qmp_commands, "query-cpu-model-expansion");
#endif
-#if !defined(TARGET_S390X)
- qmp_unregister_command(&qmp_commands, "query-cpu-model-baseline");
- qmp_unregister_command(&qmp_commands, "query-cpu-model-comparison");
-#endif
#if !defined(TARGET_PPC) && !defined(TARGET_ARM) && !defined(TARGET_I386) \
&& !defined(TARGET_S390X)
qmp_unregister_command(&qmp_commands, "query-cpu-definitions");
@@ -4152,13 +4145,6 @@ QemuOptsList qemu_mon_opts = {
},
};
-#ifndef TARGET_S390X
-void qmp_dump_skeys(const char *filename, Error **errp)
-{
- error_setg(errp, QERR_FEATURE_DISABLED, "dump-skeys");
-}
-#endif
-
#ifndef TARGET_ARM
GICCapabilityList *qmp_query_gic_capabilities(Error **errp)
{
diff --git a/qmp.c b/qmp.c
index 90816ba283..7b6861846f 100644
--- a/qmp.c
+++ b/qmp.c
@@ -553,20 +553,6 @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
return arch_query_cpu_model_expansion(type, model, errp);
}
-CpuModelCompareInfo *qmp_query_cpu_model_comparison(CpuModelInfo *modela,
- CpuModelInfo *modelb,
- Error **errp)
-{
- return arch_query_cpu_model_comparison(modela, modelb, errp);
-}
-
-CpuModelBaselineInfo *qmp_query_cpu_model_baseline(CpuModelInfo *modela,
- CpuModelInfo *modelb,
- Error **errp)
-{
- return arch_query_cpu_model_baseline(modela, modelb, errp);
-}
-
void qmp_add_client(const char *protocol, const char *fdname,
bool has_skipauth, bool skipauth, bool has_tls, bool tls,
Error **errp)
diff --git a/stubs/arch-query-cpu-model-baseline.c b/stubs/arch-query-cpu-model-baseline.c
deleted file mode 100644
index 094ec13c2c..0000000000
--- a/stubs/arch-query-cpu-model-baseline.c
+++ /dev/null
@@ -1,12 +0,0 @@
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "sysemu/arch_init.h"
-#include "qapi/qmp/qerror.h"
-
-CpuModelBaselineInfo *arch_query_cpu_model_baseline(CpuModelInfo *modela,
- CpuModelInfo *modelb,
- Error **errp)
-{
- error_setg(errp, QERR_UNSUPPORTED);
- return NULL;
-}
diff --git a/stubs/arch-query-cpu-model-comparison.c b/stubs/arch-query-cpu-model-comparison.c
deleted file mode 100644
index d5486ae980..0000000000
--- a/stubs/arch-query-cpu-model-comparison.c
+++ /dev/null
@@ -1,12 +0,0 @@
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "sysemu/arch_init.h"
-#include "qapi/qmp/qerror.h"
-
-CpuModelCompareInfo *arch_query_cpu_model_comparison(CpuModelInfo *modela,
- CpuModelInfo *modelb,
- Error **errp)
-{
- error_setg(errp, QERR_UNSUPPORTED);
- return NULL;
-}
diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index 18cbf91d9c..5f8151925a 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -25,6 +25,7 @@
#ifndef CONFIG_USER_ONLY
#include "sysemu/arch_init.h"
#endif
+#include "target-qmp-commands.h"
#define CPUDEF_INIT(_type, _gen, _ec_ga, _mha_pow, _hmfai, _name, _desc) \
{ \
@@ -562,7 +563,7 @@ static void list_add_feat(const char *name, void *opaque)
*last = entry;
}
-CpuModelCompareInfo *arch_query_cpu_model_comparison(CpuModelInfo *infoa,
+CpuModelCompareInfo *qmp_query_cpu_model_comparison(CpuModelInfo *infoa,
CpuModelInfo *infob,
Error **errp)
{
@@ -635,7 +636,7 @@ CpuModelCompareInfo *arch_query_cpu_model_comparison(CpuModelInfo *infoa,
return compare_info;
}
-CpuModelBaselineInfo *arch_query_cpu_model_baseline(CpuModelInfo *infoa,
+CpuModelBaselineInfo *qmp_query_cpu_model_baseline(CpuModelInfo *infoa,
CpuModelInfo *infob,
Error **errp)
{
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index 4a33495911..5419f0f995 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -1,7 +1,5 @@
stub-obj-y += arch-query-cpu-def.o
stub-obj-y += arch-query-cpu-model-expansion.o
-stub-obj-y += arch-query-cpu-model-comparison.o
-stub-obj-y += arch-query-cpu-model-baseline.o
stub-obj-y += bdrv-next-monitor-owned.o
stub-obj-y += blk-commit-all.o
stub-obj-y += blockdev-close-all-bdrv-states.o
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 47/50] target.json: add a note about query-cpu* not being s390x-specific
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (45 preceding siblings ...)
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 46/50] qapi: make s390 commands depend on TARGET_S390X Marc-André Lureau
@ 2017-09-11 11:06 ` Marc-André Lureau
2017-09-13 7:46 ` Cornelia Huck
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 48/50] qapi: make query-gic-capabilities depend on TARGET_ARM Marc-André Lureau
` (4 subsequent siblings)
51 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:06 UTC (permalink / raw)
To: qemu-devel; +Cc: armbru, Marc-André Lureau, Eric Blake
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qapi/target.json | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/qapi/target.json b/qapi/target.json
index 3b73a9202f..12002b54d5 100644
--- a/qapi/target.json
+++ b/qapi/target.json
@@ -77,6 +77,9 @@
# an unknown cpu definition name, unknown properties or properties
# with wrong types.
#
+# Note: this command isn't specific to s390x, but is only implemented
+# on this architecture currently.
+#
# Since: 2.8.0
##
{ 'command': 'query-cpu-model-comparison',
@@ -117,6 +120,9 @@
# an unknown cpu definition name, unknown properties or properties
# with wrong types.
#
+# Note: this command isn't specific to s390x, but is only implemented
+# on this architecture currently.
+#
# Since: 2.8.0
##
{ 'command': 'query-cpu-model-baseline',
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 48/50] qapi: make query-gic-capabilities depend on TARGET_ARM
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (46 preceding siblings ...)
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 47/50] target.json: add a note about query-cpu* not being s390x-specific Marc-André Lureau
@ 2017-09-11 11:06 ` Marc-André Lureau
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 49/50] qapi: make query-cpu-model-expansion depend on s390 or x86 Marc-André Lureau
` (3 subsequent siblings)
51 siblings, 0 replies; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:06 UTC (permalink / raw)
To: qemu-devel
Cc: armbru, Marc-André Lureau, Dr. David Alan Gilbert,
Eric Blake, Peter Maydell, open list:ARM
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qapi-schema.json | 43 -------------------------------------------
qapi/target.json | 45 +++++++++++++++++++++++++++++++++++++++++++++
monitor.c | 11 -----------
target/arm/monitor.c | 2 +-
4 files changed, 46 insertions(+), 55 deletions(-)
diff --git a/qapi-schema.json b/qapi-schema.json
index b4a5f9abc5..23151506e7 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2879,49 +2879,6 @@
##
{ 'command': 'xen-load-devices-state', 'data': {'filename': 'str'} }
-##
-# @GICCapability:
-#
-# The struct describes capability for a specific GIC (Generic
-# Interrupt Controller) version. These bits are not only decided by
-# QEMU/KVM software version, but also decided by the hardware that
-# the program is running upon.
-#
-# @version: version of GIC to be described. Currently, only 2 and 3
-# are supported.
-#
-# @emulated: whether current QEMU/hardware supports emulated GIC
-# device in user space.
-#
-# @kernel: whether current QEMU/hardware supports hardware
-# accelerated GIC device in kernel.
-#
-# Since: 2.6
-##
-{ 'struct': 'GICCapability',
- 'data': { 'version': 'int',
- 'emulated': 'bool',
- 'kernel': 'bool' } }
-
-##
-# @query-gic-capabilities:
-#
-# This command is ARM-only. It will return a list of GICCapability
-# objects that describe its capability bits.
-#
-# Returns: a list of GICCapability objects.
-#
-# Since: 2.6
-#
-# Example:
-#
-# -> { "execute": "query-gic-capabilities" }
-# <- { "return": [{ "version": 2, "emulated": true, "kernel": false },
-# { "version": 3, "emulated": false, "kernel": true } ] }
-#
-##
-{ 'command': 'query-gic-capabilities', 'returns': ['GICCapability'] }
-
##
# @CpuInstanceProperties:
#
diff --git a/qapi/target.json b/qapi/target.json
index 12002b54d5..daf4bfa8f1 100644
--- a/qapi/target.json
+++ b/qapi/target.json
@@ -130,3 +130,48 @@
'modelb': 'CpuModelInfo' },
'returns': 'CpuModelBaselineInfo',
'if': 'defined(TARGET_S390X)' }
+
+##
+# @GICCapability:
+#
+# The struct describes capability for a specific GIC (Generic
+# Interrupt Controller) version. These bits are not only decided by
+# QEMU/KVM software version, but also decided by the hardware that
+# the program is running upon.
+#
+# @version: version of GIC to be described. Currently, only 2 and 3
+# are supported.
+#
+# @emulated: whether current QEMU/hardware supports emulated GIC
+# device in user space.
+#
+# @kernel: whether current QEMU/hardware supports hardware
+# accelerated GIC device in kernel.
+#
+# Since: 2.6
+##
+{ 'struct': 'GICCapability',
+ 'data': { 'version': 'int',
+ 'emulated': 'bool',
+ 'kernel': 'bool' },
+ 'if': 'defined(TARGET_ARM)' }
+
+##
+# @query-gic-capabilities:
+#
+# This command is ARM-only. It will return a list of GICCapability
+# objects that describe its capability bits.
+#
+# Returns: a list of GICCapability objects.
+#
+# Since: 2.6
+#
+# Example:
+#
+# -> { "execute": "query-gic-capabilities" }
+# <- { "return": [{ "version": 2, "emulated": true, "kernel": false },
+# { "version": 3, "emulated": false, "kernel": true } ] }
+#
+##
+{ 'command': 'query-gic-capabilities', 'returns': ['GICCapability'],
+ 'if': 'defined(TARGET_ARM)' }
diff --git a/monitor.c b/monitor.c
index 622ba3b819..acf4721b30 100644
--- a/monitor.c
+++ b/monitor.c
@@ -971,9 +971,6 @@ static void qmp_query_qmp_schema(QDict *qdict, QObject **ret_data,
*/
static void qmp_unregister_commands_hack(void)
{
-#ifndef TARGET_ARM
- qmp_unregister_command(&qmp_commands, "query-gic-capabilities");
-#endif
#if !defined(TARGET_S390X) && !defined(TARGET_I386)
qmp_unregister_command(&qmp_commands, "query-cpu-model-expansion");
#endif
@@ -4145,14 +4142,6 @@ QemuOptsList qemu_mon_opts = {
},
};
-#ifndef TARGET_ARM
-GICCapabilityList *qmp_query_gic_capabilities(Error **errp)
-{
- error_setg(errp, QERR_FEATURE_DISABLED, "query-gic-capabilities");
- return NULL;
-}
-#endif
-
HotpluggableCPUList *qmp_query_hotpluggable_cpus(Error **errp)
{
MachineState *ms = MACHINE(qdev_get_machine());
diff --git a/target/arm/monitor.c b/target/arm/monitor.c
index 299cb80ae7..a46b0f98b4 100644
--- a/target/arm/monitor.c
+++ b/target/arm/monitor.c
@@ -20,7 +20,7 @@
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
-#include "qmp-commands.h"
+#include "target-qmp-commands.h"
#include "hw/boards.h"
#include "kvm_arm.h"
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 49/50] qapi: make query-cpu-model-expansion depend on s390 or x86
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (47 preceding siblings ...)
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 48/50] qapi: make query-gic-capabilities depend on TARGET_ARM Marc-André Lureau
@ 2017-09-11 11:06 ` Marc-André Lureau
2017-09-12 17:40 ` Eduardo Habkost
2017-09-13 7:47 ` Cornelia Huck
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 50/50] qapi: make query-cpu-definitions depend on specific targets Marc-André Lureau
` (2 subsequent siblings)
51 siblings, 2 replies; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:06 UTC (permalink / raw)
To: qemu-devel
Cc: armbru, Marc-André Lureau, Dr. David Alan Gilbert,
Eric Blake, Paolo Bonzini, Richard Henderson, Eduardo Habkost,
Alexander Graf
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qapi-schema.json | 38 ---------------------------------
qapi/target.json | 39 ++++++++++++++++++++++++++++++++++
include/sysemu/arch_init.h | 3 ---
monitor.c | 3 ---
qmp.c | 7 ------
stubs/arch-query-cpu-model-expansion.c | 12 -----------
target/i386/cpu.c | 3 ++-
target/s390x/cpu_models.c | 2 +-
stubs/Makefile.objs | 1 -
9 files changed, 42 insertions(+), 66 deletions(-)
delete mode 100644 stubs/arch-query-cpu-model-expansion.c
diff --git a/qapi-schema.json b/qapi-schema.json
index 23151506e7..98525c7702 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2020,44 +2020,6 @@
'data': { 'model': 'CpuModelInfo' } }
-##
-# @query-cpu-model-expansion:
-#
-# Expands a given CPU model (or a combination of CPU model + additional options)
-# to different granularities, allowing tooling to get an understanding what a
-# specific CPU model looks like in QEMU under a certain configuration.
-#
-# This interface can be used to query the "host" CPU model.
-#
-# The data returned by this command may be affected by:
-#
-# * QEMU version: CPU models may look different depending on the QEMU version.
-# (Except for CPU models reported as "static" in query-cpu-definitions.)
-# * machine-type: CPU model may look different depending on the machine-type.
-# (Except for CPU models reported as "static" in query-cpu-definitions.)
-# * machine options (including accelerator): in some architectures, CPU models
-# may look different depending on machine and accelerator options. (Except for
-# CPU models reported as "static" in query-cpu-definitions.)
-# * "-cpu" arguments and global properties: arguments to the -cpu option and
-# global properties may affect expansion of CPU models. Using
-# query-cpu-model-expansion while using these is not advised.
-#
-# Some architectures may not support all expansion types. s390x supports
-# "full" and "static".
-#
-# Returns: a CpuModelExpansionInfo. Returns an error if expanding CPU models is
-# not supported, if the model cannot be expanded, if the model contains
-# an unknown CPU definition name, unknown properties or properties
-# with a wrong type. Also returns an error if an expansion type is
-# not supported.
-#
-# Since: 2.8.0
-##
-{ 'command': 'query-cpu-model-expansion',
- 'data': { 'type': 'CpuModelExpansionType',
- 'model': 'CpuModelInfo' },
- 'returns': 'CpuModelExpansionInfo' }
-
##
# @CpuModelCompareResult:
#
diff --git a/qapi/target.json b/qapi/target.json
index daf4bfa8f1..d9f3bce22f 100644
--- a/qapi/target.json
+++ b/qapi/target.json
@@ -175,3 +175,42 @@
##
{ 'command': 'query-gic-capabilities', 'returns': ['GICCapability'],
'if': 'defined(TARGET_ARM)' }
+
+##
+# @query-cpu-model-expansion:
+#
+# Expands a given CPU model (or a combination of CPU model + additional options)
+# to different granularities, allowing tooling to get an understanding what a
+# specific CPU model looks like in QEMU under a certain configuration.
+#
+# This interface can be used to query the "host" CPU model.
+#
+# The data returned by this command may be affected by:
+#
+# * QEMU version: CPU models may look different depending on the QEMU version.
+# (Except for CPU models reported as "static" in query-cpu-definitions.)
+# * machine-type: CPU model may look different depending on the machine-type.
+# (Except for CPU models reported as "static" in query-cpu-definitions.)
+# * machine options (including accelerator): in some architectures, CPU models
+# may look different depending on machine and accelerator options. (Except for
+# CPU models reported as "static" in query-cpu-definitions.)
+# * "-cpu" arguments and global properties: arguments to the -cpu option and
+# global properties may affect expansion of CPU models. Using
+# query-cpu-model-expansion while using these is not advised.
+#
+# Some architectures may not support all expansion types. s390x supports
+# "full" and "static".
+#
+# Returns: a CpuModelExpansionInfo. Returns an error if expanding CPU models is
+# not supported, if the model cannot be expanded, if the model contains
+# an unknown CPU definition name, unknown properties or properties
+# with a wrong type. Also returns an error if an expansion type is
+# not supported.
+#
+# Since: 2.8.0
+##
+{ 'command': 'query-cpu-model-expansion',
+ 'data': { 'type': 'CpuModelExpansionType',
+ 'model': 'CpuModelInfo' },
+ 'returns': 'CpuModelExpansionInfo',
+ 'if': 'defined(TARGET_S390X) || defined(TARGET_I386)' }
diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index f193f5189b..08a607b89b 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -32,7 +32,4 @@ int kvm_available(void);
int xen_available(void);
CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp);
-CpuModelExpansionInfo *arch_query_cpu_model_expansion(CpuModelExpansionType type,
- CpuModelInfo *mode,
- Error **errp);
#endif
diff --git a/monitor.c b/monitor.c
index acf4721b30..24680f37a6 100644
--- a/monitor.c
+++ b/monitor.c
@@ -971,9 +971,6 @@ static void qmp_query_qmp_schema(QDict *qdict, QObject **ret_data,
*/
static void qmp_unregister_commands_hack(void)
{
-#if !defined(TARGET_S390X) && !defined(TARGET_I386)
- qmp_unregister_command(&qmp_commands, "query-cpu-model-expansion");
-#endif
#if !defined(TARGET_PPC) && !defined(TARGET_ARM) && !defined(TARGET_I386) \
&& !defined(TARGET_S390X)
qmp_unregister_command(&qmp_commands, "query-cpu-definitions");
diff --git a/qmp.c b/qmp.c
index 7b6861846f..afa266ec1e 100644
--- a/qmp.c
+++ b/qmp.c
@@ -546,13 +546,6 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
return arch_query_cpu_definitions(errp);
}
-CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
- CpuModelInfo *model,
- Error **errp)
-{
- return arch_query_cpu_model_expansion(type, model, errp);
-}
-
void qmp_add_client(const char *protocol, const char *fdname,
bool has_skipauth, bool skipauth, bool has_tls, bool tls,
Error **errp)
diff --git a/stubs/arch-query-cpu-model-expansion.c b/stubs/arch-query-cpu-model-expansion.c
deleted file mode 100644
index ae7cf554d1..0000000000
--- a/stubs/arch-query-cpu-model-expansion.c
+++ /dev/null
@@ -1,12 +0,0 @@
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "sysemu/arch_init.h"
-#include "qapi/qmp/qerror.h"
-
-CpuModelExpansionInfo *arch_query_cpu_model_expansion(CpuModelExpansionType type,
- CpuModelInfo *mode,
- Error **errp)
-{
- error_setg(errp, QERR_UNSUPPORTED);
- return NULL;
-}
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 69676e13e1..f8719cb2de 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -36,6 +36,7 @@
#include "qapi/visitor.h"
#include "qom/qom-qobject.h"
#include "sysemu/arch_init.h"
+#include "target-qmp-commands.h"
#if defined(CONFIG_KVM)
#include <linux/kvm_para.h>
@@ -2618,7 +2619,7 @@ out:
}
CpuModelExpansionInfo *
-arch_query_cpu_model_expansion(CpuModelExpansionType type,
+qmp_query_cpu_model_expansion(CpuModelExpansionType type,
CpuModelInfo *model,
Error **errp)
{
diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index 5f8151925a..872dc78455 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -524,7 +524,7 @@ static void cpu_info_from_model(CpuModelInfo *info, const S390CPUModel *model,
}
}
-CpuModelExpansionInfo *arch_query_cpu_model_expansion(CpuModelExpansionType type,
+CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
CpuModelInfo *model,
Error **errp)
{
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index 5419f0f995..8d024a2b71 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -1,5 +1,4 @@
stub-obj-y += arch-query-cpu-def.o
-stub-obj-y += arch-query-cpu-model-expansion.o
stub-obj-y += bdrv-next-monitor-owned.o
stub-obj-y += blk-commit-all.o
stub-obj-y += blockdev-close-all-bdrv-states.o
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* [Qemu-devel] [PATCH v3 50/50] qapi: make query-cpu-definitions depend on specific targets
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (48 preceding siblings ...)
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 49/50] qapi: make query-cpu-model-expansion depend on s390 or x86 Marc-André Lureau
@ 2017-09-11 11:06 ` Marc-André Lureau
2017-09-12 17:45 ` Eduardo Habkost
2017-09-13 7:48 ` Cornelia Huck
2017-09-11 11:54 ` [Qemu-devel] [PATCH v3 00/50] Hi, no-reply
2017-12-18 13:14 ` Markus Armbruster
51 siblings, 2 replies; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-11 11:06 UTC (permalink / raw)
To: qemu-devel
Cc: armbru, Marc-André Lureau, Dr. David Alan Gilbert,
Eric Blake, Paolo Bonzini, Peter Maydell, Richard Henderson,
Eduardo Habkost, David Gibson, Alexander Graf, open list:ARM,
open list:PowerPC
It depends on TARGET_PPC || TARGET_ARM || TARGET_I386 || TARGET_S390X.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qapi-schema.json | 11 -----------
qapi/target.json | 12 ++++++++++++
include/sysemu/arch_init.h | 1 -
monitor.c | 22 ----------------------
qmp.c | 5 -----
stubs/arch-query-cpu-def.c | 10 ----------
target/arm/helper.c | 3 ++-
target/i386/cpu.c | 2 +-
target/ppc/translate_init.c | 3 ++-
target/s390x/cpu_models.c | 2 +-
stubs/Makefile.objs | 1 -
11 files changed, 18 insertions(+), 54 deletions(-)
delete mode 100644 stubs/arch-query-cpu-def.c
diff --git a/qapi-schema.json b/qapi-schema.json
index 98525c7702..975f2fd30f 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1945,17 +1945,6 @@
'data': { 'name': 'str', '*migration-safe': 'bool', 'static': 'bool',
'*unavailable-features': [ 'str' ], 'typename': 'str' } }
-##
-# @query-cpu-definitions:
-#
-# Return a list of supported virtual CPU definitions
-#
-# Returns: a list of CpuDefInfo
-#
-# Since: 1.2.0
-##
-{ 'command': 'query-cpu-definitions', 'returns': ['CpuDefinitionInfo'] }
-
##
# @CpuModelInfo:
#
diff --git a/qapi/target.json b/qapi/target.json
index d9f3bce22f..e06c9e3ed7 100644
--- a/qapi/target.json
+++ b/qapi/target.json
@@ -214,3 +214,15 @@
'model': 'CpuModelInfo' },
'returns': 'CpuModelExpansionInfo',
'if': 'defined(TARGET_S390X) || defined(TARGET_I386)' }
+
+##
+# @query-cpu-definitions:
+#
+# Return a list of supported virtual CPU definitions
+#
+# Returns: a list of CpuDefInfo
+#
+# Since: 1.2.0
+##
+{ 'command': 'query-cpu-definitions', 'returns': ['CpuDefinitionInfo'],
+ 'if': 'defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_I386) || defined(TARGET_S390X)' }
diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index 08a607b89b..e9721b9ce8 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -31,5 +31,4 @@ extern const uint32_t arch_type;
int kvm_available(void);
int xen_available(void);
-CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp);
#endif
diff --git a/monitor.c b/monitor.c
index 24680f37a6..00fb1bbf4e 100644
--- a/monitor.c
+++ b/monitor.c
@@ -957,26 +957,6 @@ static void qmp_query_qmp_schema(QDict *qdict, QObject **ret_data,
*ret_data = qobject_from_qlit(&qmp_schema_qlit);
}
-/*
- * We used to define commands in qmp-commands.hx in addition to the
- * QAPI schema. This permitted defining some of them only in certain
- * configurations. query-commands has always reflected that (good,
- * because it lets QMP clients figure out what's actually available),
- * while query-qmp-schema never did (not so good). This function is a
- * hack to keep the configuration-specific commands defined exactly as
- * before, even though qmp-commands.hx is gone.
- *
- * FIXME Educate the QAPI schema on configuration-specific commands,
- * and drop this hack.
- */
-static void qmp_unregister_commands_hack(void)
-{
-#if !defined(TARGET_PPC) && !defined(TARGET_ARM) && !defined(TARGET_I386) \
- && !defined(TARGET_S390X)
- qmp_unregister_command(&qmp_commands, "query-cpu-definitions");
-#endif
-}
-
void monitor_init_qmp_commands(void)
{
/*
@@ -998,8 +978,6 @@ void monitor_init_qmp_commands(void)
qmp_register_command(&qmp_commands, "netdev_add", qmp_netdev_add,
QCO_NO_OPTIONS);
- qmp_unregister_commands_hack();
-
QTAILQ_INIT(&qmp_cap_negotiation_commands);
qmp_register_command(&qmp_cap_negotiation_commands, "qmp_capabilities",
qmp_marshal_qmp_capabilities, QCO_NO_OPTIONS);
diff --git a/qmp.c b/qmp.c
index afa266ec1e..d57ccf1251 100644
--- a/qmp.c
+++ b/qmp.c
@@ -541,11 +541,6 @@ DevicePropertyInfoList *qmp_device_list_properties(const char *typename,
return prop_list;
}
-CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
-{
- return arch_query_cpu_definitions(errp);
-}
-
void qmp_add_client(const char *protocol, const char *fdname,
bool has_skipauth, bool skipauth, bool has_tls, bool tls,
Error **errp)
diff --git a/stubs/arch-query-cpu-def.c b/stubs/arch-query-cpu-def.c
deleted file mode 100644
index cefe4beb82..0000000000
--- a/stubs/arch-query-cpu-def.c
+++ /dev/null
@@ -1,10 +0,0 @@
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "sysemu/arch_init.h"
-#include "qapi/qmp/qerror.h"
-
-CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
-{
- error_setg(errp, QERR_UNSUPPORTED);
- return NULL;
-}
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 329e5178d8..b3ea771fcd 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -15,6 +15,7 @@
#include <zlib.h> /* For crc32 */
#include "exec/semihost.h"
#include "sysemu/kvm.h"
+#include "target-qmp-commands.h"
#define ARM_CPU_FREQ 1000000000 /* FIXME: 1 GHz, should be configurable */
@@ -5327,7 +5328,7 @@ static void arm_cpu_add_definition(gpointer data, gpointer user_data)
*cpu_list = entry;
}
-CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
+CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
{
CpuDefinitionInfoList *cpu_list = NULL;
GSList *list;
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index f8719cb2de..9cd1dee1a5 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -2363,7 +2363,7 @@ static void x86_cpu_definition_entry(gpointer data, gpointer user_data)
*cpu_list = entry;
}
-CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
+CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
{
CpuDefinitionInfoList *cpu_list = NULL;
GSList *list = get_sorted_cpu_model_list();
diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
index c827d1e388..680352f953 100644
--- a/target/ppc/translate_init.c
+++ b/target/ppc/translate_init.c
@@ -35,6 +35,7 @@
#include "mmu-book3s-v3.h"
#include "sysemu/qtest.h"
#include "qemu/cutils.h"
+#include "target-qmp-commands.h"
//#define PPC_DUMP_CPU
//#define PPC_DEBUG_SPR
@@ -10415,7 +10416,7 @@ static void ppc_cpu_defs_entry(gpointer data, gpointer user_data)
*first = entry;
}
-CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
+CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
{
CpuDefinitionInfoList *cpu_list = NULL;
GSList *list;
diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index 872dc78455..26c9fff79c 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -390,7 +390,7 @@ static void create_cpu_model_list(ObjectClass *klass, void *opaque)
*cpu_list = entry;
}
-CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
+CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
{
struct CpuDefinitionInfoListData list_data = {
.list = NULL,
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index 8d024a2b71..22e9197dcd 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -1,4 +1,3 @@
-stub-obj-y += arch-query-cpu-def.o
stub-obj-y += bdrv-next-monitor-owned.o
stub-obj-y += blk-commit-all.o
stub-obj-y += blockdev-close-all-bdrv-states.o
--
2.14.1.146.gd35faa819
^ permalink raw reply related [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 00/50] Hi,
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (49 preceding siblings ...)
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 50/50] qapi: make query-cpu-definitions depend on specific targets Marc-André Lureau
@ 2017-09-11 11:54 ` no-reply
2017-12-18 13:14 ` Markus Armbruster
51 siblings, 0 replies; 118+ messages in thread
From: no-reply @ 2017-09-11 11:54 UTC (permalink / raw)
To: marcandre.lureau; +Cc: famz, qemu-devel, armbru
Hi,
This series failed automatic build test. Please find the testing commands and
their output below. If you have docker installed, you can probably reproduce it
locally.
Subject: [Qemu-devel] [PATCH v3 00/50] Hi,
Message-id: 20170911110623.24981-1-marcandre.lureau@redhat.com
Type: series
=== TEST SCRIPT BEGIN ===
#!/bin/bash
set -e
git submodule update --init dtc
# Let docker tests dump environment info
export SHOW_ENV=1
export J=8
time make docker-test-quick@centos6
time make docker-test-build@min-glib
time make docker-test-mingw@fedora
=== TEST SCRIPT END ===
Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
1d8781c86a qapi: make query-cpu-definitions depend on specific targets
c1814694c2 qapi: make query-cpu-model-expansion depend on s390 or x86
bd74091ade qapi: make query-gic-capabilities depend on TARGET_ARM
1d28b98dd1 target.json: add a note about query-cpu* not being s390x-specific
c7b9cba7dd qapi: make s390 commands depend on TARGET_S390X
b131645e5f qapi: make rtc-reset-reinjection depend on TARGET_I386
960aaa74bb build-sys: add a target schema
e3f318c8c3 build-sys: move qmp-introspect per target
71eab793c2 qapi: add a -u/--unit option to specify which unit to visit
9d165fe81e qapi: add a 'unit' pragma
e7ea04e24b qapi: add -i/--include filename.h
fbf22f44fa qapi-commands: don't initialize command list in qmp_init_marshall()
6def7fd06b qapi: add conditions to REPLICATION type/commands on the schema
043aba6677 qapi: add conditions to SPICE type/commands/events on the schema
cd14f015e5 qapi: add conditions to VNC type/commands/events on the schema
0aa323bee5 qapi2texi: add condition to variants
2b93c585fc qapi2texi: add 'If:' condition to struct members
bb70e84669 qapi2texi: add 'If:' condition to enum values
fd7b62cdac qapi2texi: add 'If:' section to generated documentation
44b2c49aa0 docs: document schema configuration
1cac828e3b qapi: add #if conditions to generated alternate variants
b8c8b93c51 qapi: add tests for invalid alternate
7594ba7d28 qapi: add 'if' to alternate variant
25e10a0b8a qapi: add #if conditions to generated variants
bd9efd8521 qapi: add 'if' on union variants
e82ba63f9d qapi: add #if conditions to generated struct members
cff07c1587 qapi: add some struct member tests
fd66601eec qapi: add 'if' to struct members and implicit objects members
c75e5f0c86 tests: add some enum members tests
450301d6d6 qapi: add #if conditions on generated enum members
be66ae92a3 qapi-event: add 'if' condition to generated enum
c248455099 qapi: add 'if' to enum members
ec649c084c qapi: change enum visitor to take QAPISchemaMember
a3635c5ed0 qapi: do not define enumeration value explicitely
a3de6080f9 qapi-types: add #if conditions to types & visitors
bf00d931ab qapi-types: refactor variants handling
2620d8539e qapi-event: add #if conditions to events
9afa67c39b qapi-commands: add #if conditions to commands
6016203f71 qapi-introspect: add preprocessor conditions to generated QLit
1d1970308c qapi-introspect: modify to_qlit() to generate #if code
10a53e0e87 qapi-introspect: modify to_qlit() to append ', ' on level > 0
8c1cf63678 qapi: add #if/#endif helpers
8029ce5875 qapi: mcgen() shouldn't indent # lines
1780e303b8 qapi: add 'ifcond' to visitor methods
dd93a5bdb8 qapi: pass 'if' condition into QAPISchemaEntity objects
b2df076279 qapi: add tests for invalid 'if'
186e9297f0 qapi: add 'if' to top-level expressions
0032b622c7 qapi2texi: minor python code simplification
347ba5193c qapi: generate a literal qobject for introspection
150a7e19aa qlit: add qobject_from_qlit()
=== OUTPUT BEGIN ===
Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path 'dtc'
Cloning into '/var/tmp/patchew-tester-tmp-g9aaw526/src/dtc'...
Submodule path 'dtc': checked out '558cd81bdd432769b59bff01240c44f82cfb1a9d'
BUILD centos6
make[1]: Entering directory '/var/tmp/patchew-tester-tmp-g9aaw526/src'
ARCHIVE qemu.tgz
ARCHIVE dtc.tgz
COPY RUNNER
RUN test-quick in qemu:centos6
Packages installed:
SDL-devel-1.2.14-7.el6_7.1.x86_64
bison-2.4.1-5.el6.x86_64
bzip2-devel-1.0.5-7.el6_0.x86_64
ccache-3.1.6-2.el6.x86_64
csnappy-devel-0-6.20150729gitd7bc683.el6.x86_64
flex-2.5.35-9.el6.x86_64
gcc-4.4.7-18.el6.x86_64
git-1.7.1-8.el6.x86_64
glib2-devel-2.28.8-9.el6.x86_64
libepoxy-devel-1.2-3.el6.x86_64
libfdt-devel-1.4.0-1.el6.x86_64
librdmacm-devel-1.0.21-0.el6.x86_64
lzo-devel-2.03-3.1.el6_5.1.x86_64
make-3.81-23.el6.x86_64
mesa-libEGL-devel-11.0.7-4.el6.x86_64
mesa-libgbm-devel-11.0.7-4.el6.x86_64
package g++ is not installed
pixman-devel-0.32.8-1.el6.x86_64
spice-glib-devel-0.26-8.el6.x86_64
spice-server-devel-0.12.4-16.el6.x86_64
tar-1.23-15.el6_8.x86_64
vte-devel-0.25.1-9.el6.x86_64
xen-devel-4.6.3-15.el6.x86_64
zlib-devel-1.2.3-29.el6.x86_64
Environment variables:
PACKAGES=bison bzip2-devel ccache csnappy-devel flex g++ gcc git glib2-devel libepoxy-devel libfdt-devel librdmacm-devel lzo-devel make mesa-libEGL-devel mesa-libgbm-devel pixman-devel SDL-devel spice-glib-devel spice-server-devel tar vte-devel xen-devel zlib-devel
HOSTNAME=b98b51bd7e45
TERM=xterm
MAKEFLAGS= -j8
HISTSIZE=1000
J=8
USER=root
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.tbz=01;31:*.tbz2=01;31:*.bz=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:
CCACHE_DIR=/var/tmp/ccache
EXTRA_CONFIGURE_OPTS=
V=
SHOW_ENV=1
MAIL=/var/spool/mail/root
PATH=/usr/lib/ccache:/usr/lib64/ccache:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
LANG=en_US.UTF-8
TARGET_LIST=
HISTCONTROL=ignoredups
SHLVL=1
HOME=/root
TEST_DIR=/tmp/qemu-test
LOGNAME=root
LESSOPEN=||/usr/bin/lesspipe.sh %s
FEATURES= dtc
DEBUG=
G_BROKEN_FILENAMES=1
CCACHE_HASHDIR=
_=/usr/bin/env
Configure options:
--enable-werror --target-list=x86_64-softmmu,aarch64-softmmu --prefix=/var/tmp/qemu-build/install
No C++ compiler available; disabling C++ specific optional code
Install prefix /var/tmp/qemu-build/install
BIOS directory /var/tmp/qemu-build/install/share/qemu
binary directory /var/tmp/qemu-build/install/bin
library directory /var/tmp/qemu-build/install/lib
module directory /var/tmp/qemu-build/install/lib/qemu
libexec directory /var/tmp/qemu-build/install/libexec
include directory /var/tmp/qemu-build/install/include
config directory /var/tmp/qemu-build/install/etc
local state directory /var/tmp/qemu-build/install/var
Manual directory /var/tmp/qemu-build/install/share/man
ELF interp prefix /usr/gnemul/qemu-%M
Source path /tmp/qemu-test/src
C compiler cc
Host C compiler cc
C++ compiler
Objective-C compiler cc
ARFLAGS rv
CFLAGS -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -g
QEMU_CFLAGS -I/usr/include/pixman-1 -I$(SRC_PATH)/dtc/libfdt -pthread -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -DNCURSES_WIDECHAR -fPIE -DPIE -m64 -mcx16 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wstrict-prototypes -Wredundant-decls -Wall -Wundef -Wwrite-strings -Wmissing-prototypes -fno-strict-aliasing -fno-common -fwrapv -Wendif-labels -Wno-missing-include-dirs -Wempty-body -Wnested-externs -Wformat-security -Wformat-y2k -Winit-self -Wignored-qualifiers -Wold-style-declaration -Wold-style-definition -Wtype-limits -fstack-protector-all -I/usr/include/libpng12 -I/usr/include/libdrm -I/usr/include/spice-server -I/usr/include/cacard -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/nss3 -I/usr/include/nspr4 -I/usr/include/spice-1 -I/usr/include/cacard -I/usr/include/nss3 -I/usr/include/nspr4
LDFLAGS -Wl,--warn-common -Wl,-z,relro -Wl,-z,now -pie -m64 -g
make make
install install
python python -B
smbd /usr/sbin/smbd
module support no
host CPU x86_64
host big endian no
target list x86_64-softmmu aarch64-softmmu
gprof enabled no
sparse enabled no
strip binaries yes
profiler no
static build no
pixman system
SDL support yes (1.2.14)
GTK support yes (2.24.23)
GTK GL support no
VTE support yes (0.25.1)
TLS priority NORMAL
GNUTLS support no
GNUTLS rnd no
libgcrypt no
libgcrypt kdf no
nettle no
nettle kdf no
libtasn1 no
curses support yes
virgl support no
curl support no
mingw32 support no
Audio drivers oss
Block whitelist (rw)
Block whitelist (ro)
VirtFS support no
VNC support yes
VNC SASL support no
VNC JPEG support yes
VNC PNG support yes
xen support yes
xen ctrl version 40600
pv dom build no
brlapi support no
bluez support no
Documentation no
PIE yes
vde support no
netmap support no
Linux AIO support no
ATTR/XATTR support yes
Install blobs yes
KVM support yes
HAX support no
TCG support yes
TCG debug enabled no
TCG interpreter no
RDMA support yes
fdt support yes
preadv support yes
fdatasync yes
madvise yes
posix_madvise yes
libcap-ng support no
vhost-net support yes
vhost-scsi support yes
vhost-vsock support yes
vhost-user support yes
Trace backends log
spice support yes (0.12.6/0.12.4)
rbd support no
xfsctl support no
smartcard support yes
libusb no
usb net redir no
OpenGL support yes
OpenGL dmabufs no
libiscsi support no
libnfs support no
build guest agent yes
QGA VSS support no
QGA w32 disk info no
QGA MSI support no
seccomp support no
coroutine backend ucontext
coroutine pool yes
debug stack usage no
crypto afalg no
GlusterFS support no
gcov gcov
gcov enabled no
TPM support yes
libssh2 support no
TPM passthrough yes
QOM debugging yes
Live block migration yes
lzo support yes
snappy support no
bzip2 support yes
NUMA host support no
tcmalloc support no
jemalloc support no
avx2 optimization no
replication support yes
VxHS block device no
mkdir -p dtc/libfdt
mkdir -p dtc/tests
GEN x86_64-softmmu/config-devices.mak.tmp
GEN aarch64-softmmu/config-devices.mak.tmp
GEN qemu-options.def
GEN config-host.h
GEN qmp-commands.h
GEN qapi-types.h
GEN qapi-visit.h
Traceback (most recent call last):
File "/tmp/qemu-test/src/scripts/qapi-commands.py", line 15, in <module>
from qapi import *
File "/tmp/qemu-test/src/scripts/qapi.py", line 714
check_unknown_keys(info, value, {'type', 'if'})
^
SyntaxError: invalid syntax
GEN qapi-event.h
make: *** [qmp-commands.h] Error 1
make: *** Waiting for unfinished jobs....
Traceback (most recent call last):
File "/tmp/qemu-test/src/scripts/qapi-visit.py", line 15, in <module>
from qapi import *
File "/tmp/qemu-test/src/scripts/qapi.py", line 714
check_unknown_keys(info, value, {'type', 'if'})
^
SyntaxError: invalid syntax
Traceback (most recent call last):
File "/tmp/qemu-test/src/scripts/qapi-types.py", line 14, in <module>
from qapi import *
File "/tmp/qemu-test/src/scripts/qapi.py", line 714
check_unknown_keys(info, value, {'type', 'if'})
^
SyntaxError: invalid syntax
make: *** [qapi-visit.h] Error 1
make: *** [qapi-types.h] Error 1
GEN aarch64-softmmu/config-devices.mak
Traceback (most recent call last):
File "/tmp/qemu-test/src/scripts/qapi-event.py", line 14, in <module>
from qapi import *
File "/tmp/qemu-test/src/scripts/qapi.py", line 714
check_unknown_keys(info, value, {'type', 'if'})
^
SyntaxError: invalid syntax
make: *** [qapi-event.h] Error 1
GEN x86_64-softmmu/config-devices.mak
Traceback (most recent call last):
File "./tests/docker/docker.py", line 384, in <module>
sys.exit(main())
File "./tests/docker/docker.py", line 381, in main
return args.cmdobj.run(args, argv)
File "./tests/docker/docker.py", line 239, in run
return Docker().run(argv, args.keep, quiet=args.quiet)
File "./tests/docker/docker.py", line 207, in run
quiet=quiet)
File "./tests/docker/docker.py", line 125, in _do_check
return subprocess.check_call(self._command + cmd, **kwargs)
File "/usr/lib64/python2.7/subprocess.py", line 186, in check_call
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['docker', 'run', '--label', 'com.qemu.instance.uuid=d7268e7a96e711e7b25b52540069c830', '-u', '0', '-t', '--rm', '--net=none', '-e', 'TARGET_LIST=', '-e', 'EXTRA_CONFIGURE_OPTS=', '-e', 'V=', '-e', 'J=8', '-e', 'DEBUG=', '-e', 'SHOW_ENV=1', '-e', 'CCACHE_DIR=/var/tmp/ccache', '-v', '/var/tmp/patchew-tester-tmp-g9aaw526/src/docker-src.2017-09-11-07.53.31.9321:/var/tmp/qemu:z,ro', '-v', '/root/.cache/qemu-docker-ccache:/var/tmp/ccache:z', 'qemu:centos6', '/var/tmp/qemu/run', 'test-quick']' returned non-zero exit status 2
make[1]: *** [tests/docker/Makefile.include:139: docker-run] Error 1
make[1]: Leaving directory '/var/tmp/patchew-tester-tmp-g9aaw526/src'
make: *** [tests/docker/Makefile.include:168: docker-run-test-quick@centos6] Error 2
real 1m12.628s
user 0m5.082s
sys 0m1.662s
=== OUTPUT END ===
Test command exited with code: 2
---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 49/50] qapi: make query-cpu-model-expansion depend on s390 or x86
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 49/50] qapi: make query-cpu-model-expansion depend on s390 or x86 Marc-André Lureau
@ 2017-09-12 17:40 ` Eduardo Habkost
2017-09-13 7:47 ` Cornelia Huck
1 sibling, 0 replies; 118+ messages in thread
From: Eduardo Habkost @ 2017-09-12 17:40 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, armbru, Dr. David Alan Gilbert, Eric Blake,
Paolo Bonzini, Richard Henderson, Alexander Graf
On Mon, Sep 11, 2017 at 01:06:22PM +0200, Marc-André Lureau wrote:
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
--
Eduardo
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 50/50] qapi: make query-cpu-definitions depend on specific targets
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 50/50] qapi: make query-cpu-definitions depend on specific targets Marc-André Lureau
@ 2017-09-12 17:45 ` Eduardo Habkost
2017-09-13 7:48 ` Cornelia Huck
1 sibling, 0 replies; 118+ messages in thread
From: Eduardo Habkost @ 2017-09-12 17:45 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, armbru, Dr. David Alan Gilbert, Eric Blake,
Paolo Bonzini, Peter Maydell, Richard Henderson, David Gibson,
Alexander Graf, open list:ARM, open list:PowerPC
On Mon, Sep 11, 2017 at 01:06:23PM +0200, Marc-André Lureau wrote:
> It depends on TARGET_PPC || TARGET_ARM || TARGET_I386 || TARGET_S390X.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
--
Eduardo
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 46/50] qapi: make s390 commands depend on TARGET_S390X
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 46/50] qapi: make s390 commands depend on TARGET_S390X Marc-André Lureau
@ 2017-09-13 7:45 ` Cornelia Huck
0 siblings, 0 replies; 118+ messages in thread
From: Cornelia Huck @ 2017-09-13 7:45 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, armbru, Richard Henderson, Alexander Graf,
Christian Borntraeger, Dr. David Alan Gilbert, Eric Blake,
Paolo Bonzini
On Mon, 11 Sep 2017 13:06:19 +0200
Marc-André Lureau <marcandre.lureau@redhat.com> wrote:
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> qapi-schema.json | 101 -------------------------------
> qapi/target.json | 104 ++++++++++++++++++++++++++++++++
> include/sysemu/arch_init.h | 7 ---
> hw/s390x/s390-skeys.c | 2 +-
> monitor.c | 14 -----
> qmp.c | 14 -----
> stubs/arch-query-cpu-model-baseline.c | 12 ----
> stubs/arch-query-cpu-model-comparison.c | 12 ----
> target/s390x/cpu_models.c | 5 +-
> stubs/Makefile.objs | 2 -
> 10 files changed, 108 insertions(+), 165 deletions(-)
> delete mode 100644 stubs/arch-query-cpu-model-baseline.c
> delete mode 100644 stubs/arch-query-cpu-model-comparison.c
Together with the next patch (which makes clear that the cpu model
functions are not s390x-specific, but currently only implemented there):
Acked-by: Cornelia Huck <cohuck@redhat.com>
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 47/50] target.json: add a note about query-cpu* not being s390x-specific
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 47/50] target.json: add a note about query-cpu* not being s390x-specific Marc-André Lureau
@ 2017-09-13 7:46 ` Cornelia Huck
0 siblings, 0 replies; 118+ messages in thread
From: Cornelia Huck @ 2017-09-13 7:46 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, armbru
On Mon, 11 Sep 2017 13:06:20 +0200
Marc-André Lureau <marcandre.lureau@redhat.com> wrote:
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> qapi/target.json | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/qapi/target.json b/qapi/target.json
> index 3b73a9202f..12002b54d5 100644
> --- a/qapi/target.json
> +++ b/qapi/target.json
> @@ -77,6 +77,9 @@
> # an unknown cpu definition name, unknown properties or properties
> # with wrong types.
> #
> +# Note: this command isn't specific to s390x, but is only implemented
> +# on this architecture currently.
> +#
> # Since: 2.8.0
> ##
> { 'command': 'query-cpu-model-comparison',
> @@ -117,6 +120,9 @@
> # an unknown cpu definition name, unknown properties or properties
> # with wrong types.
> #
> +# Note: this command isn't specific to s390x, but is only implemented
> +# on this architecture currently.
> +#
> # Since: 2.8.0
> ##
> { 'command': 'query-cpu-model-baseline',
Acked-by: Cornelia Huck <cohuck@redhat.com>
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 49/50] qapi: make query-cpu-model-expansion depend on s390 or x86
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 49/50] qapi: make query-cpu-model-expansion depend on s390 or x86 Marc-André Lureau
2017-09-12 17:40 ` Eduardo Habkost
@ 2017-09-13 7:47 ` Cornelia Huck
1 sibling, 0 replies; 118+ messages in thread
From: Cornelia Huck @ 2017-09-13 7:47 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Alexander Graf, Eduardo Habkost, armbru,
Dr. David Alan Gilbert, Paolo Bonzini, Richard Henderson
On Mon, 11 Sep 2017 13:06:22 +0200
Marc-André Lureau <marcandre.lureau@redhat.com> wrote:
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> qapi-schema.json | 38 ---------------------------------
> qapi/target.json | 39 ++++++++++++++++++++++++++++++++++
> include/sysemu/arch_init.h | 3 ---
> monitor.c | 3 ---
> qmp.c | 7 ------
> stubs/arch-query-cpu-model-expansion.c | 12 -----------
> target/i386/cpu.c | 3 ++-
> target/s390x/cpu_models.c | 2 +-
> stubs/Makefile.objs | 1 -
> 9 files changed, 42 insertions(+), 66 deletions(-)
> delete mode 100644 stubs/arch-query-cpu-model-expansion.c
Acked-by: Cornelia Huck <cohuck@redhat.com>
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 50/50] qapi: make query-cpu-definitions depend on specific targets
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 50/50] qapi: make query-cpu-definitions depend on specific targets Marc-André Lureau
2017-09-12 17:45 ` Eduardo Habkost
@ 2017-09-13 7:48 ` Cornelia Huck
1 sibling, 0 replies; 118+ messages in thread
From: Cornelia Huck @ 2017-09-13 7:48 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Peter Maydell, Eduardo Habkost, armbru,
Dr. David Alan Gilbert, Alexander Graf, open list:ARM,
open list:PowerPC, Paolo Bonzini, David Gibson,
Richard Henderson
On Mon, 11 Sep 2017 13:06:23 +0200
Marc-André Lureau <marcandre.lureau@redhat.com> wrote:
> It depends on TARGET_PPC || TARGET_ARM || TARGET_I386 || TARGET_S390X.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> qapi-schema.json | 11 -----------
> qapi/target.json | 12 ++++++++++++
> include/sysemu/arch_init.h | 1 -
> monitor.c | 22 ----------------------
> qmp.c | 5 -----
> stubs/arch-query-cpu-def.c | 10 ----------
> target/arm/helper.c | 3 ++-
> target/i386/cpu.c | 2 +-
> target/ppc/translate_init.c | 3 ++-
> target/s390x/cpu_models.c | 2 +-
> stubs/Makefile.objs | 1 -
> 11 files changed, 18 insertions(+), 54 deletions(-)
> delete mode 100644 stubs/arch-query-cpu-def.c
Acked-by: Cornelia Huck <cohuck@redhat.com>
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 01/50] qlit: add qobject_from_qlit()
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 01/50] qlit: add qobject_from_qlit() Marc-André Lureau
@ 2017-09-13 13:51 ` Eric Blake
2017-09-13 14:08 ` Marc-André Lureau
2017-12-06 14:37 ` Markus Armbruster
1 sibling, 1 reply; 118+ messages in thread
From: Eric Blake @ 2017-09-13 13:51 UTC (permalink / raw)
To: Marc-André Lureau, qemu-devel; +Cc: armbru
[-- Attachment #1: Type: text/plain, Size: 1523 bytes --]
On 09/11/2017 06:05 AM, Marc-André Lureau wrote:
> Instanciate a QObject* form a literal QLitObject.
s/Instanciate/Instantiate/
s/form/from/
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> include/qapi/qmp/qlit.h | 2 ++
> qobject/qlit.c | 36 ++++++++++++++++++++++++++++++++++++
> tests/check-qlit.c | 26 ++++++++++++++++++++++++++
> 3 files changed, 64 insertions(+)
> +QObject *qobject_from_qlit(const QLitObject *qlit)
> +{
> + switch (qlit->type) {
> + case QTYPE_QNULL:
> + return QOBJECT(qnull());
> + case QTYPE_QNUM:
> + return QOBJECT(qnum_from_int(qlit->value.qnum));
Is this going to work for all QNum values?
> +++ 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);
Related to my question above - you pass because there are no floating
point values in qlit. Is that something we want supported?
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3266
Virtualization: qemu.org | libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 619 bytes --]
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 01/50] qlit: add qobject_from_qlit()
2017-09-13 13:51 ` Eric Blake
@ 2017-09-13 14:08 ` Marc-André Lureau
2017-12-06 14:37 ` Markus Armbruster
0 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-09-13 14:08 UTC (permalink / raw)
To: Eric Blake; +Cc: qemu-devel, armbru
----- Original Message -----
> On 09/11/2017 06:05 AM, Marc-André Lureau wrote:
> > Instanciate a QObject* form a literal QLitObject.
>
> s/Instanciate/Instantiate/
> s/form/from/
thanks
>
> >
> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> > ---
> > include/qapi/qmp/qlit.h | 2 ++
> > qobject/qlit.c | 36 ++++++++++++++++++++++++++++++++++++
> > tests/check-qlit.c | 26 ++++++++++++++++++++++++++
> > 3 files changed, 64 insertions(+)
>
> > +QObject *qobject_from_qlit(const QLitObject *qlit)
> > +{
> > + switch (qlit->type) {
> > + case QTYPE_QNULL:
> > + return QOBJECT(qnull());
> > + case QTYPE_QNUM:
> > + return QOBJECT(qnum_from_int(qlit->value.qnum));
>
> Is this going to work for all QNum values?
>
> > +++ 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);
>
> Related to my question above - you pass because there are no floating
> point values in qlit. Is that something we want supported?
Markus had some remarks about it when reviewing #define QLIT_QNUM. Only i64 are supported at this point, so it's left for whoever requires it in the future.
>
> --
> Eric Blake, Principal Software Engineer
> Red Hat, Inc. +1-919-301-3266
> Virtualization: qemu.org | libvirt.org
>
>
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 01/50] qlit: add qobject_from_qlit()
2017-09-13 14:08 ` Marc-André Lureau
@ 2017-12-06 14:37 ` Markus Armbruster
0 siblings, 0 replies; 118+ messages in thread
From: Markus Armbruster @ 2017-12-06 14:37 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: Eric Blake, qemu-devel
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> ----- Original Message -----
>> On 09/11/2017 06:05 AM, Marc-André Lureau wrote:
>> > Instanciate a QObject* form a literal QLitObject.
>>
>> s/Instanciate/Instantiate/
>> s/form/from/
>
> thanks
>
>>
>> >
>> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>> > ---
>> > include/qapi/qmp/qlit.h | 2 ++
>> > qobject/qlit.c | 36 ++++++++++++++++++++++++++++++++++++
>> > tests/check-qlit.c | 26 ++++++++++++++++++++++++++
>> > 3 files changed, 64 insertions(+)
>>
>> > +QObject *qobject_from_qlit(const QLitObject *qlit)
>> > +{
>> > + switch (qlit->type) {
>> > + case QTYPE_QNULL:
>> > + return QOBJECT(qnull());
>> > + case QTYPE_QNUM:
>> > + return QOBJECT(qnum_from_int(qlit->value.qnum));
>>
>> Is this going to work for all QNum values?
>>
>> > +++ 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);
>>
>> Related to my question above - you pass because there are no floating
>> point values in qlit. Is that something we want supported?
>
> Markus had some remarks about it when reviewing #define QLIT_QNUM. Only i64 are supported at this point, so it's left for whoever requires it in the future.
Yes, QLitObject only supports int64_t for now. uint64_t and double
aren't implemented.
By the way, shouldn't QLitObject member type be QType instead of int?
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 01/50] qlit: add qobject_from_qlit()
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 01/50] qlit: add qobject_from_qlit() Marc-André Lureau
2017-09-13 13:51 ` Eric Blake
@ 2017-12-06 14:37 ` Markus Armbruster
1 sibling, 0 replies; 118+ messages in thread
From: Markus Armbruster @ 2017-12-06 14:37 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Instanciate a QObject* form a literal QLitObject.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> include/qapi/qmp/qlit.h | 2 ++
> qobject/qlit.c | 36 ++++++++++++++++++++++++++++++++++++
> tests/check-qlit.c | 26 ++++++++++++++++++++++++++
> 3 files changed, 64 insertions(+)
>
> diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h
> index b18406bce9..56feb25e04 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 3c4882c784..df2ad97d33 100644
> --- a/qobject/qlit.c
> +++ b/qobject/qlit.c
> @@ -82,3 +82,39 @@ bool qlit_equal_qobject(const QLitObject *lhs, const QObject *rhs)
>
> return false;
> }
> +
> +QObject *qobject_from_qlit(const QLitObject *qlit)
> +{
> + 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();
> + QLitDictEntry *e;
> +
> + for (e = qlit->value.qdict; e->key; e++) {
> + qdict_put_obj(qdict, e->key, qobject_from_qlit(&e->value));
> + }
> + return QOBJECT(qdict);
> + }
> + case QTYPE_QLIST: {
> + QList *qlist = qlist_new();
> + QLitObject *e;
> +
> + for (e = qlit->value.qlist; e->type != QTYPE_NONE; e++) {
> + qlist_append_obj(qlist, qobject_from_qlit(e));
> + }
> + return QOBJECT(qlist);
> + }
> + case QTYPE_QBOOL:
> + return QOBJECT(qbool_from_bool(qlit->value.qbool));
> + case QTYPE_NONE:
Please make that
default:
to remove the compiler's license to have the function return null on
corrupted qlit->type. If compilers gripe unless you keep case
QTYPE_NONE in place, keep it.
> + assert(0);
> + }
> +
> + return NULL;
> +}
> diff --git a/tests/check-qlit.c b/tests/check-qlit.c
> index c59ec1ab88..acd6e02e96 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();
> }
With the assertion tightened and the typos pointed out by Eric fixed:
Reviewed-by: Markus Armbruster <armbru@redhat.com>
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 02/50] qapi: generate a literal qobject for introspection
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 02/50] qapi: generate a literal qobject for introspection Marc-André Lureau
@ 2017-12-06 15:17 ` Markus Armbruster
0 siblings, 0 replies; 118+ messages in thread
From: Markus Armbruster @ 2017-12-06 15:17 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Michael Roth, Dr. David Alan Gilbert
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> 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>
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 03/50] qapi2texi: minor python code simplification
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 03/50] qapi2texi: minor python code simplification Marc-André Lureau
@ 2017-12-06 15:19 ` Markus Armbruster
0 siblings, 0 replies; 118+ messages in thread
From: Markus Armbruster @ 2017-12-06 15:19 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Michael Roth
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 04/50] qapi: add 'if' to top-level expressions
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 04/50] qapi: add 'if' to top-level expressions Marc-André Lureau
@ 2017-12-06 15:46 ` Markus Armbruster
2017-12-06 16:23 ` Markus Armbruster
1 sibling, 0 replies; 118+ messages in thread
From: Markus Armbruster @ 2017-12-06 15:46 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Michael Roth
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Accept 'if' key in top-level elements, accepted as string or list of
> string type. The following patches will modify the test visitor to
> check the value is correctly saved, and generate #if/#endif code (as a
> single #if/endif line or a series for a list).
>
> Example of 'if' key:
> { 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
> 'if': 'defined(TEST_IF_STRUCT)' }
>
> The generated code is for now *unconditional*. Later patches generate
> the conditionals.
>
> A following patch for qapi-code-gen.txt will provide more complete
> documentation for 'if' usage.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 04/50] qapi: add 'if' to top-level expressions
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 04/50] qapi: add 'if' to top-level expressions Marc-André Lureau
2017-12-06 15:46 ` Markus Armbruster
@ 2017-12-06 16:23 ` Markus Armbruster
1 sibling, 0 replies; 118+ messages in thread
From: Markus Armbruster @ 2017-12-06 16:23 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Michael Roth
Second thoughts...
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Accept 'if' key in top-level elements, accepted as string or list of
> string type. The following patches will modify the test visitor to
> check the value is correctly saved, and generate #if/#endif code (as a
> single #if/endif line or a series for a list).
>
> Example of 'if' key:
> { 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
> 'if': 'defined(TEST_IF_STRUCT)' }
>
> The generated code is for now *unconditional*. Later patches generate
> the conditionals.
>
> A following patch for qapi-code-gen.txt will provide more complete
> documentation for 'if' usage.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi.py | 35 +++++++++++++++++++++++++++------
> tests/test-qmp-commands.c | 6 ++++++
> tests/qapi-schema/qapi-schema-test.json | 20 +++++++++++++++++++
> tests/qapi-schema/qapi-schema-test.out | 22 +++++++++++++++++++++
> 4 files changed, 77 insertions(+), 6 deletions(-)
>
> diff --git a/scripts/qapi.py b/scripts/qapi.py
> index 62dc52ed6e..20c1abf915 100644
> --- a/scripts/qapi.py
> +++ b/scripts/qapi.py
> @@ -639,6 +639,26 @@ def add_name(name, info, meta, implicit=False):
> all_names[name] = meta
>
>
> +def check_if(expr, info):
> +
> + def check_if_str(ifcond, info):
> + if ifcond == '':
> + raise QAPISemError(info, "'if' condition '' makes no sense")
> +
> + ifcond = expr['if']
> + if isinstance(ifcond, str):
> + check_if_str(ifcond, info)
> + elif (isinstance(ifcond, list)
> + and all(isinstance(elt, str) for elt in ifcond)):
> + if ifcond == []:
> + raise QAPISemError(info, "'if' condition [] is useless")
> + for elt in ifcond:
> + check_if_str(elt, info)
> + else:
> + raise QAPISemError(
> + info, "'if' condition must be a string or a list of strings")
> +
> +
Slightly terser:
def check_if(expr, info):
def check_if_str(ifcond, info):
if not isinstance(ifcond, str):
raise QAPISemError(
info, "'if' condition must be a string or a list of strings")
if ifcond == '':
raise QAPISemError(info, "'if' condition '' makes no sense")
ifcond = expr['if']
if isinstance(ifcond, list):
if ifcond == []:
raise QAPISemError(info, "'if' condition [] is useless")
for elt in ifcond:
check_if_str(elt, info)
else:
check_if_str(ifcond, info)
Can slot this in on commit.
> def check_type(info, source, value, allow_array=False,
> allow_dict=False, allow_optional=False,
> allow_metas=[]):
[...]
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 05/50] qapi: add tests for invalid 'if'
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 05/50] qapi: add tests for invalid 'if' Marc-André Lureau
@ 2017-12-06 16:34 ` Markus Armbruster
0 siblings, 0 replies; 118+ messages in thread
From: Markus Armbruster @ 2017-12-06 16:34 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Michael Roth
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
This tests error conditions added in the previous commit. I recommend
squashing the two together.
> ---
> tests/Makefile.include | 3 +++
> tests/qapi-schema/bad-if-empty-list.err | 1 +
> tests/qapi-schema/bad-if-empty-list.exit | 1 +
> tests/qapi-schema/bad-if-empty-list.json | 3 +++
> tests/qapi-schema/bad-if-empty-list.out | 0
> tests/qapi-schema/bad-if-empty.err | 1 +
> tests/qapi-schema/bad-if-empty.exit | 1 +
> tests/qapi-schema/bad-if-empty.json | 3 +++
> tests/qapi-schema/bad-if-empty.out | 0
> tests/qapi-schema/bad-if.err | 1 +
> tests/qapi-schema/bad-if.exit | 1 +
> tests/qapi-schema/bad-if.json | 3 +++
> tests/qapi-schema/bad-if.out | 0
> 13 files changed, 18 insertions(+)
> create mode 100644 tests/qapi-schema/bad-if-empty-list.err
> create mode 100644 tests/qapi-schema/bad-if-empty-list.exit
> create mode 100644 tests/qapi-schema/bad-if-empty-list.json
> create mode 100644 tests/qapi-schema/bad-if-empty-list.out
> create mode 100644 tests/qapi-schema/bad-if-empty.err
> create mode 100644 tests/qapi-schema/bad-if-empty.exit
> create mode 100644 tests/qapi-schema/bad-if-empty.json
> create mode 100644 tests/qapi-schema/bad-if-empty.out
> create mode 100644 tests/qapi-schema/bad-if.err
> create mode 100644 tests/qapi-schema/bad-if.exit
> create mode 100644 tests/qapi-schema/bad-if.json
> create mode 100644 tests/qapi-schema/bad-if.out
>
> diff --git a/tests/Makefile.include b/tests/Makefile.include
> index fae5715e9c..8dac7c9083 100644
> --- a/tests/Makefile.include
> +++ b/tests/Makefile.include
> @@ -402,6 +402,9 @@ qapi-schema += args-unknown.json
> qapi-schema += bad-base.json
> qapi-schema += bad-data.json
> qapi-schema += bad-ident.json
> +qapi-schema += bad-if.json
> +qapi-schema += bad-if-empty.json
> +qapi-schema += bad-if-empty-list.json
> qapi-schema += bad-type-bool.json
> qapi-schema += bad-type-dict.json
> qapi-schema += bad-type-int.json
> diff --git a/tests/qapi-schema/bad-if-empty-list.err b/tests/qapi-schema/bad-if-empty-list.err
> new file mode 100644
> index 0000000000..75fe6497bc
> --- /dev/null
> +++ b/tests/qapi-schema/bad-if-empty-list.err
> @@ -0,0 +1 @@
> +tests/qapi-schema/bad-if-empty-list.json:2: 'if' condition [] is useless
> diff --git a/tests/qapi-schema/bad-if-empty-list.exit b/tests/qapi-schema/bad-if-empty-list.exit
> new file mode 100644
> index 0000000000..d00491fd7e
> --- /dev/null
> +++ b/tests/qapi-schema/bad-if-empty-list.exit
> @@ -0,0 +1 @@
> +1
> diff --git a/tests/qapi-schema/bad-if-empty-list.json b/tests/qapi-schema/bad-if-empty-list.json
> new file mode 100644
> index 0000000000..94f2eb8670
> --- /dev/null
> +++ b/tests/qapi-schema/bad-if-empty-list.json
> @@ -0,0 +1,3 @@
> +# check empty 'if' list
> +{ 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
> + 'if': [] }
> diff --git a/tests/qapi-schema/bad-if-empty-list.out b/tests/qapi-schema/bad-if-empty-list.out
> new file mode 100644
> index 0000000000..e69de29bb2
This covers "'if' condition [] is useless".
> diff --git a/tests/qapi-schema/bad-if-empty.err b/tests/qapi-schema/bad-if-empty.err
> new file mode 100644
> index 0000000000..358bdc3e51
> --- /dev/null
> +++ b/tests/qapi-schema/bad-if-empty.err
> @@ -0,0 +1 @@
> +tests/qapi-schema/bad-if-empty.json:2: 'if' condition '' makes no sense
> diff --git a/tests/qapi-schema/bad-if-empty.exit b/tests/qapi-schema/bad-if-empty.exit
> new file mode 100644
> index 0000000000..d00491fd7e
> --- /dev/null
> +++ b/tests/qapi-schema/bad-if-empty.exit
> @@ -0,0 +1 @@
> +1
> diff --git a/tests/qapi-schema/bad-if-empty.json b/tests/qapi-schema/bad-if-empty.json
> new file mode 100644
> index 0000000000..fe1dd4eca6
> --- /dev/null
> +++ b/tests/qapi-schema/bad-if-empty.json
> @@ -0,0 +1,3 @@
> +# check empty 'if'
> +{ 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
> + 'if': '' }
> diff --git a/tests/qapi-schema/bad-if-empty.out b/tests/qapi-schema/bad-if-empty.out
> new file mode 100644
> index 0000000000..e69de29bb2
This covers "'if' condition '' makes no sense", not wrapped in a list.
> diff --git a/tests/qapi-schema/bad-if.err b/tests/qapi-schema/bad-if.err
> new file mode 100644
> index 0000000000..c2e3f5f44c
> --- /dev/null
> +++ b/tests/qapi-schema/bad-if.err
> @@ -0,0 +1 @@
> +tests/qapi-schema/bad-if.json:2: 'if' condition must be a string or a list of strings
> diff --git a/tests/qapi-schema/bad-if.exit b/tests/qapi-schema/bad-if.exit
> new file mode 100644
> index 0000000000..d00491fd7e
> --- /dev/null
> +++ b/tests/qapi-schema/bad-if.exit
> @@ -0,0 +1 @@
> +1
> diff --git a/tests/qapi-schema/bad-if.json b/tests/qapi-schema/bad-if.json
> new file mode 100644
> index 0000000000..3edd1a0bf2
> --- /dev/null
> +++ b/tests/qapi-schema/bad-if.json
> @@ -0,0 +1,3 @@
> +# check invalid 'if' type
> +{ 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
> + 'if': { 'value': 'defined(TEST_IF_STRUCT)' } }
> diff --git a/tests/qapi-schema/bad-if.out b/tests/qapi-schema/bad-if.out
> new file mode 100644
> index 0000000000..e69de29bb2
This covers "'if' condition must be a string or a list of strings", not
wrapped in a list.
Not covered: the two not wrapped in a list cases wrapped in a list.
However, I figure this is good enough as is, thus
Reviewed-by: Markus Armbruster <armbru@redhat.com>
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 06/50] qapi: pass 'if' condition into QAPISchemaEntity objects
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 06/50] qapi: pass 'if' condition into QAPISchemaEntity objects Marc-André Lureau
@ 2017-12-06 17:13 ` Markus Armbruster
0 siblings, 0 replies; 118+ messages in thread
From: Markus Armbruster @ 2017-12-06 17:13 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Michael Roth
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Built-in objects remain unconditional. Explicitly defined objects
> use the condition specified in the schema. Implicitly defined
> objects inherit their condition from their users. For most of them,
> there is exactly one user, so the condition to use is obvious. The
> exception is the wrapper types generated for simple union variants,
> which can be shared by any number of simple unions. The tight
> condition would be the disjunction of the conditions of these simple
> unions. For now, use wrapped type's condition instead. Much
the wrapped type's
> simpler and good enough for now.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi.py | 89 ++++++++++++++++++++++++++++++++++++---------------------
> 1 file changed, 57 insertions(+), 32 deletions(-)
>
> diff --git a/scripts/qapi.py b/scripts/qapi.py
> index 20c1abf915..0f55caa18d 100644
> --- a/scripts/qapi.py
> +++ b/scripts/qapi.py
> @@ -1000,7 +1000,7 @@ def check_exprs(exprs):
> #
>
> class QAPISchemaEntity(object):
> - def __init__(self, name, info, doc):
> + def __init__(self, name, info, doc, ifcond=None):
> assert isinstance(name, str)
> self.name = name
> # For explicitly defined entities, info points to the (explicit)
> @@ -1010,6 +1010,7 @@ class QAPISchemaEntity(object):
> # such place).
> self.info = info
> self.doc = doc
> + self.ifcond = ifcond
>
> def c_name(self):
> return c_name(self.name)
> @@ -1126,8 +1127,8 @@ class QAPISchemaBuiltinType(QAPISchemaType):
>
>
> class QAPISchemaEnumType(QAPISchemaType):
> - def __init__(self, name, info, doc, values, prefix):
> - QAPISchemaType.__init__(self, name, info, doc)
> + def __init__(self, name, info, doc, ifcond, values, prefix):
> + QAPISchemaType.__init__(self, name, info, doc, ifcond)
> for v in values:
> assert isinstance(v, QAPISchemaMember)
> v.set_owner(name)
> @@ -1162,7 +1163,7 @@ class QAPISchemaEnumType(QAPISchemaType):
>
> class QAPISchemaArrayType(QAPISchemaType):
> def __init__(self, name, info, element_type):
> - QAPISchemaType.__init__(self, name, info, None)
> + QAPISchemaType.__init__(self, name, info, None, None)
> assert isinstance(element_type, str)
> self._element_type_name = element_type
> self.element_type = None
> @@ -1170,6 +1171,7 @@ class QAPISchemaArrayType(QAPISchemaType):
> def check(self, schema):
> self.element_type = schema.lookup_type(self._element_type_name)
> assert self.element_type
> + self.ifcond = self.element_type.ifcond
>
> def is_implicit(self):
> return True
In my review of v2, I wrote:
This is subtler than it looks on first glance.
All the other entities set self.ifcond in their constructor to the true
value passed in as argument.
QAPISchemaArrayType doesn't take such an argument. Instead, it inherits
its .ifcond from its .element_type. However, .element_type isn't known
at construction time if it's a forward reference. We therefore delay
setting it until .check() time. You do the same for .ifcond (no
choice).
Before .check(), .ifcond is None, because the constructor sets it that
way: it calls QAPISchemaType.__init__() without passing a ifcond
argument, which then sets self.ifcond to its default argument None.
Pitfall: accessing ent.ifcond before ent.check() works *except* when ent
is an array type. Hmm.
The problem is of course more general. We commonly initialize
attributes to None in .init(), then set their real value in .check().
Accessing the attribute before .check() yields None. If we're lucky,
the code that accesses the attribute prematurely chokes on None.
It won't for .ifcond, because None is a legitimate value.
Perhaps we should leave such attributes undefined until .check(). What
do you think? No need to tie that idea to this series, though.
[...]
With the commit message tidied up:
Reviewed-by: Markus Armbruster <armbru@redhat.com>
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 07/50] qapi: add 'ifcond' to visitor methods
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 07/50] qapi: add 'ifcond' to visitor methods Marc-André Lureau
@ 2017-12-06 17:23 ` Markus Armbruster
0 siblings, 0 replies; 118+ messages in thread
From: Markus Armbruster @ 2017-12-06 17:23 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Michael Roth
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Modify the test visitor to check correct passing of values.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 08/50] qapi: mcgen() shouldn't indent # lines
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 08/50] qapi: mcgen() shouldn't indent # lines Marc-André Lureau
@ 2017-12-06 17:41 ` Markus Armbruster
0 siblings, 0 replies; 118+ messages in thread
From: Markus Armbruster @ 2017-12-06 17:41 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Michael Roth
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Skip preprocessor lines when adding indentation, since that would
> likely result in invalid code.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi.py | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/scripts/qapi.py b/scripts/qapi.py
> index f2b5a7e131..2a8e60e975 100644
> --- a/scripts/qapi.py
> +++ b/scripts/qapi.py
> @@ -1862,7 +1862,7 @@ def cgen(code, **kwds):
> if indent_level:
> indent = genindent(indent_level)
> # re.subn() lacks flags support before Python 2.7, use re.compile()
> - raw = re.subn(re.compile(r'^.', re.MULTILINE),
> + raw = re.subn(re.compile(r'^[^#\n].', re.MULTILINE),
> indent + r'\g<0>', raw)
> raw = raw[0]
> return re.sub(re.escape(eatspace) + r' *', '', raw)
Old: we want to indent all non-empty lines. Such a line starts with a
character other than newline, matched by '.'. Replace that character by
indent + the character.
New regexp: we want to indent all non-empty lines not starting with '#'.
Such a line starts with a character other than newline and '#', matched
by '[^#\n]'. But there's a '.' afterwards, and therefore we don't match
*any* lines consisting of just one character:
>>> cgen('a\n')
'a\n'
I think you should drop the '.'.
Alternatively, use a negative lookahead assertion:
raw = re.subn(re.compile(r'^(?!(#|$))', re.MULTILINE),
indent, raw)
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 09/50] qapi: add #if/#endif helpers
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 09/50] qapi: add #if/#endif helpers Marc-André Lureau
@ 2017-12-07 14:10 ` Markus Armbruster
2018-01-11 21:21 ` Marc-André Lureau
0 siblings, 1 reply; 118+ messages in thread
From: Markus Armbruster @ 2017-12-07 14:10 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Michael Roth
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Add helpers to wrap generated code with #if/#endif lines.
>
> Add a function decorator that will be used to wrap visitor methods.
> The decorator will check if code was generated before adding #if/#endif
> lines. Used in the following patches.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi.py | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 55 insertions(+)
>
> diff --git a/scripts/qapi.py b/scripts/qapi.py
> index 2a8e60e975..94b735d8d6 100644
> --- a/scripts/qapi.py
> +++ b/scripts/qapi.py
> @@ -1897,6 +1897,61 @@ def guardend(name):
> name=guardname(name))
>
>
> +def gen_if(ifcond):
> + if not ifcond:
> + return ''
> + if isinstance(ifcond, str):
> + ifcond = [ifcond]
Perhaps we should take this normalization step in the QAPISchema
constructors.
> + ret = ''
> + for ifc in ifcond:
> + ret += mcgen('''
> +#if %(cond)s
> +''', cond=ifc)
> + return ret
> +
> +
> +def gen_endif(ifcond):
> + if not ifcond:
> + return ''
> + if isinstance(ifcond, str):
> + ifcond = [ifcond]
> + ret = ''
> + for ifc in reversed(ifcond):
> + ret += mcgen('''
> +#endif /* %(cond)s */
> +''', cond=ifc)
> + return ret
> +
> +
> +# Wrap a method to add #if / #endif to generated code, only if some
> +# code was generated. The method must have an 'ifcond' argument.
> +# self must have 'if_members' listing the attributes to wrap.
> +def ifcond_decorator(func):
> +
> + def func_wrapper(self, *args, **kwargs):
> + import inspect
Is hiding imports in function a good idea?
> + idx = inspect.getargspec(func).args.index('ifcond')
> + ifcond = args[idx - 1]
> + save = {}
> + for mem in self.if_members:
> + save[mem] = getattr(self, mem)
> + func(self, *args, **kwargs)
> + for mem, val in save.items():
> + newval = getattr(self, mem)
> + if newval != val:
> + assert newval.startswith(val)
> + newval = newval[len(val):]
> + if newval[0] == '\n':
> + val += '\n'
> + newval = newval[1:]
> + val += gen_if(ifcond)
> + val += newval
> + val += gen_endif(ifcond)
> + setattr(self, mem, val)
> +
> + return func_wrapper
> +
> +
> def gen_enum_lookup(name, values, prefix=None):
> ret = mcgen('''
My gut feeling is still "too clever by half", but i'm reserving
judgement until after review of its use, and exploration of
alternatives.
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 10/50] qapi-introspect: modify to_qlit() to append ', ' on level > 0
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 10/50] qapi-introspect: modify to_qlit() to append ', ' on level > 0 Marc-André Lureau
@ 2017-12-07 14:47 ` Markus Armbruster
0 siblings, 0 replies; 118+ messages in thread
From: Markus Armbruster @ 2017-12-07 14:47 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Michael Roth
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> The following patch is going to break list entries with #if/#endif, so
> they should have the trailing ',' as suffix.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi-introspect.py | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
> index 56c1f9d548..b1d08ec97b 100644
> --- a/scripts/qapi-introspect.py
> +++ b/scripts/qapi-introspect.py
> @@ -29,7 +29,7 @@ def to_qlit(obj, level=0, suppress_first_indent=False):
> for elt in obj]
> elts.append(indent(level + 1) + "{}")
> ret += 'QLIT_QLIST(((QLitObject[]) {\n'
> - ret += ',\n'.join(elts) + '\n'
> + ret += '\n'.join(elts) + '\n'
> ret += indent(level) + '}))'
> elif isinstance(obj, dict):
> elts = []
> @@ -42,6 +42,8 @@ def to_qlit(obj, level=0, suppress_first_indent=False):
> ret += indent(level) + '}))'
> else:
> assert False # not implemented
> + if level > 0:
> + ret += ','
> return ret
Reviewed-by: Markus Armbruster <armbru@redhat.com>
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 11/50] qapi-introspect: modify to_qlit() to generate #if code
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 11/50] qapi-introspect: modify to_qlit() to generate #if code Marc-André Lureau
@ 2017-12-07 14:50 ` Markus Armbruster
0 siblings, 0 replies; 118+ messages in thread
From: Markus Armbruster @ 2017-12-07 14:50 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Michael Roth
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> The generator now accepts (obj, condition) tuples to wrap generated
> QLit objects for 'obj' with #if/#endif conditions.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi-introspect.py | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
> index b1d08ec97b..dc70954e8a 100644
> --- a/scripts/qapi-introspect.py
> +++ b/scripts/qapi-introspect.py
> @@ -17,6 +17,13 @@ def to_qlit(obj, level=0, suppress_first_indent=False):
> def indent(level):
> return level * 4 * ' '
>
> + if isinstance(obj, tuple):
> + ifobj, ifcond = obj
> + ret = gen_if(ifcond)
> + ret += to_qlit(ifobj, level)
> + ret += '\n' + gen_endif(ifcond)
> + return ret
> +
> ret = ''
> if not suppress_first_indent:
> ret += indent(level)
Reviewed-by: Markus Armbruster <armbru@redhat.com>
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 12/50] qapi-introspect: add preprocessor conditions to generated QLit
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 12/50] qapi-introspect: add preprocessor conditions to generated QLit Marc-André Lureau
@ 2017-12-07 15:41 ` Markus Armbruster
0 siblings, 0 replies; 118+ messages in thread
From: Markus Armbruster @ 2017-12-07 15:41 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Michael Roth
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Add 'ifcond' condition to top-level QLit objects.
>
> to_qlit() handles the (obj, ifcond) tuples in previous patch.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
According to my testing, this patch adds blank lines between the
elements of qmp_schema_qlit. I suspect this is because to_qlit((obj,
None) is not actually equivalent to to_qlit(obj). It should be.
Note that the issue is in PATCH 11, but becomes visible only in PATCH
12, because the new code only gets used in PATCH 12. Consider squashing
the two together.
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 15/50] qapi-types: refactor variants handling
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 15/50] qapi-types: refactor variants handling Marc-André Lureau
@ 2017-12-07 15:57 ` Markus Armbruster
2018-01-11 21:22 ` Marc-André Lureau
0 siblings, 1 reply; 118+ messages in thread
From: Markus Armbruster @ 2017-12-07 15:57 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Michael Roth
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Generate variants objects outside gen_object(). This will allow to
> easily wrap gen_object() with ifcond_decorator in the following patch.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi-types.py | 37 +++++++++++++++++++++++--------------
> 1 file changed, 23 insertions(+), 14 deletions(-)
>
> diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
> index 915786c463..2b3588267b 100644
> --- a/scripts/qapi-types.py
> +++ b/scripts/qapi-types.py
> @@ -53,23 +53,27 @@ def gen_struct_members(members):
> return ret
>
>
> -def gen_object(name, base, members, variants):
> - if name in objects_seen:
> - return ''
> - objects_seen.add(name)
> -
> +def gen_variants_objects(variants):
> ret = ''
> if variants:
> for v in variants.variants:
> if isinstance(v.type, QAPISchemaObjectType):
> + ret += gen_variants_objects(v.type.variants)
> ret += gen_object(v.type.name, v.type.base,
> v.type.local_members, v.type.variants)
> + return ret
>
> - ret += mcgen('''
> +
> +def gen_object(name, base, members, variants):
> + if name in objects_seen:
> + return ''
> + objects_seen.add(name)
> +
> + ret = mcgen('''
>
> struct %(c_name)s {
> ''',
> - c_name=c_name(name))
> + c_name=c_name(name))
>
> if base:
> if not base.is_implicit():
> @@ -218,11 +222,7 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
> self.decl += gen_array(name, element_type)
> self._gen_type_cleanup(name)
>
> - def visit_object_type(self, name, info, ifcond, base, members, variants):
> - # Nothing to do for the special empty builtin
> - if name == 'q_empty':
> - return
> - self._fwdecl += gen_fwd_object_or_array(name)
> + def _gen_object(self, name, info, ifcond, base, members, variants):
> self.decl += gen_object(name, base, members, variants)
> if base and not base.is_implicit():
> self.decl += gen_upcast(name, base)
> @@ -232,10 +232,19 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
> # implicit types won't be directly allocated/freed
> self._gen_type_cleanup(name)
>
> + def visit_object_type(self, name, info, ifcond, base, members, variants):
> + # Nothing to do for the special empty builtin
> + if name == 'q_empty':
> + return
> + self._fwdecl += gen_fwd_object_or_array(name)
> + self.decl += gen_variants_objects(variants)
> + self._gen_object(name, info, None, base, members, variants)
> +
> def visit_alternate_type(self, name, info, ifcond, variants):
> self._fwdecl += gen_fwd_object_or_array(name)
> - self.decl += gen_object(name, None, [variants.tag_member], variants)
> - self._gen_type_cleanup(name)
> + self.decl += gen_variants_objects(variants)
> + self._gen_object(name, info, None, None,
> + [variants.tag_member], variants)
Where did self._gen_type_cleanup(name) go? Hmm, I guess it's now in
_gen_object(). Confusing.
>
> # If you link code generated from multiple schemata, you want only one
> # instance of the code for built-in types. Generate it only when
If I read this patch correctly, you move code from the beginning of
gen_object() to new gen_variants_objects(), then arrange to have
gen_variants_objects() called right before gen_object(). Correct?
In old gen_object(), the code is guarded by
if name in objects_seen:
return ''
objects_seen.add(name)
In new gen_variants_objects(), it isn't. Why?
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 17/50] qapi: do not define enumeration value explicitely
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 17/50] qapi: do not define enumeration value explicitely Marc-André Lureau
@ 2017-12-07 16:23 ` Markus Armbruster
2017-12-07 17:01 ` Marc-André Lureau
0 siblings, 1 reply; 118+ messages in thread
From: Markus Armbruster @ 2017-12-07 16:23 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Michael Roth
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> The C standard has the initial value at 0 and the subsequent values
> incremented by 1. No need to set this explicitely.
>
> This will prevent from artificial "gaps" when compiling out some enum
> values and having unnecessarily large MAX values & enums arrays.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi.py | 7 ++-----
> 1 file changed, 2 insertions(+), 5 deletions(-)
>
> diff --git a/scripts/qapi.py b/scripts/qapi.py
> index 94b735d8d6..074ee221a1 100644
> --- a/scripts/qapi.py
> +++ b/scripts/qapi.py
> @@ -1985,14 +1985,11 @@ typedef enum %(c_name)s {
> ''',
> c_name=c_name(name))
>
> - i = 0
> for value in enum_values:
> ret += mcgen('''
> - %(c_enum)s = %(i)d,
> + %(c_enum)s,
> ''',
> - c_enum=c_enum_const(name, value, prefix),
> - i=i)
> - i += 1
> + c_enum=c_enum_const(name, value, prefix))
>
> ret += mcgen('''
> } %(c_name)s;
Recapitulate review of v2: this risks entertaining mishaps like
compiling this one
typedef enum Color {
COLOR_WHITE,
#if defined(NEED_CPU_H)
#if defined(TARGET_S390X)
COLOR_BLUE,
#endif /* defined(TARGET_S390X) */
#endif /* defined(NEED_CPU_H) */
COLOR_BLACK,
} Color;
in s390x-code (COLOR_BLACK = 2) and in target-independent code
(COLOR_BLACK = 1), then linking the two together.
Same issue for struct members and such (previous patch).
What's our story on preventing disaster here?
In the long run, we want to split the generated code so that
target-specific and target-independent code are separate, and each part
is always compiled with consistent preprocessor symbols. But I'm afraid
that's not in the card right now.
I therefore proposed the stupidest temporary stopgap that could possibly
work: apply conditionals *only* to qmp-introspect.c, leave everything
unconditional elsewhere.
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 17/50] qapi: do not define enumeration value explicitely
2017-12-07 16:23 ` Markus Armbruster
@ 2017-12-07 17:01 ` Marc-André Lureau
2017-12-08 7:50 ` Markus Armbruster
0 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-12-07 17:01 UTC (permalink / raw)
To: Markus Armbruster; +Cc: QEMU, Michael Roth
On Thu, Dec 7, 2017 at 5:23 PM, Markus Armbruster <armbru@redhat.com> wrote:
> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>
>> The C standard has the initial value at 0 and the subsequent values
>> incremented by 1. No need to set this explicitely.
>>
>> This will prevent from artificial "gaps" when compiling out some enum
>> values and having unnecessarily large MAX values & enums arrays.
>>
>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>> ---
>> scripts/qapi.py | 7 ++-----
>> 1 file changed, 2 insertions(+), 5 deletions(-)
>>
>> diff --git a/scripts/qapi.py b/scripts/qapi.py
>> index 94b735d8d6..074ee221a1 100644
>> --- a/scripts/qapi.py
>> +++ b/scripts/qapi.py
>> @@ -1985,14 +1985,11 @@ typedef enum %(c_name)s {
>> ''',
>> c_name=c_name(name))
>>
>> - i = 0
>> for value in enum_values:
>> ret += mcgen('''
>> - %(c_enum)s = %(i)d,
>> + %(c_enum)s,
>> ''',
>> - c_enum=c_enum_const(name, value, prefix),
>> - i=i)
>> - i += 1
>> + c_enum=c_enum_const(name, value, prefix))
>>
>> ret += mcgen('''
>> } %(c_name)s;
>
> Recapitulate review of v2: this risks entertaining mishaps like
> compiling this one
>
> typedef enum Color {
> COLOR_WHITE,
> #if defined(NEED_CPU_H)
> #if defined(TARGET_S390X)
> COLOR_BLUE,
> #endif /* defined(TARGET_S390X) */
> #endif /* defined(NEED_CPU_H) */
> COLOR_BLACK,
> } Color;
>
> in s390x-code (COLOR_BLACK = 2) and in target-independent code
> (COLOR_BLACK = 1), then linking the two together.
>
> Same issue for struct members and such (previous patch).
>
> What's our story on preventing disaster here?
>
> In the long run, we want to split the generated code so that
> target-specific and target-independent code are separate, and each part
> is always compiled with consistent preprocessor symbols. But I'm afraid
> that's not in the card right now.
Eh, I need to refresh my memories about that series, but I think
that's what I did in v3
It doesn't use the NEED_CPU_H trick. It has a seperate per-target target.json
>
> I therefore proposed the stupidest temporary stopgap that could possibly
> work: apply conditionals *only* to qmp-introspect.c, leave everything
> unconditional elsewhere.
I don't like that idea much and I don't think we need that
restriction, but I need to get back to that series on some point
(probably after you finish the review).
--
Marc-André Lureau
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 18/50] qapi: change enum visitor to take QAPISchemaMember
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 18/50] qapi: change enum visitor to take QAPISchemaMember Marc-André Lureau
@ 2017-12-07 17:34 ` Markus Armbruster
0 siblings, 0 replies; 118+ messages in thread
From: Markus Armbruster @ 2017-12-07 17:34 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Michael Roth
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> This will allow to add and access more properties associated with enum
> values/members, like the associated 'if' condition. We may want to
> have a specialized type QAPISchemaEnumMember, for now this will do.
>
> Suggested-by: Markus Armbruster <armbru@redhat.com>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi.py | 40 +++++++++++++-------------
> scripts/qapi-event.py | 2 +-
> scripts/qapi-introspect.py | 5 ++--
> scripts/qapi-types.py | 10 +++----
> scripts/qapi-visit.py | 2 +-
> scripts/qapi2texi.py | 2 +-
> tests/qapi-schema/comments.out | 14 +++++++--
> tests/qapi-schema/doc-good.out | 17 +++++++++--
> tests/qapi-schema/empty.out | 9 +++++-
> tests/qapi-schema/event-case.out | 9 +++++-
> tests/qapi-schema/ident-with-escape.out | 9 +++++-
> tests/qapi-schema/include-relpath.out | 14 +++++++--
> tests/qapi-schema/include-repetition.out | 14 +++++++--
> tests/qapi-schema/include-simple.out | 14 +++++++--
> tests/qapi-schema/indented-expr.out | 9 +++++-
> tests/qapi-schema/qapi-schema-test.out | 49 ++++++++++++++++++++++++++------
> tests/qapi-schema/test-qapi.py | 17 +++++++----
> 17 files changed, 177 insertions(+), 59 deletions(-)
>
> diff --git a/scripts/qapi.py b/scripts/qapi.py
> index 074ee221a1..386a577a59 100644
> --- a/scripts/qapi.py
> +++ b/scripts/qapi.py
> @@ -1039,7 +1039,7 @@ class QAPISchemaVisitor(object):
> def visit_builtin_type(self, name, info, json_type):
> pass
>
> - def visit_enum_type(self, name, info, ifcond, values, prefix):
> + def visit_enum_type(self, name, info, ifcond, members, prefix):
> pass
>
> def visit_array_type(self, name, info, ifcond, element_type):
> @@ -1127,21 +1127,21 @@ class QAPISchemaBuiltinType(QAPISchemaType):
>
>
> class QAPISchemaEnumType(QAPISchemaType):
> - def __init__(self, name, info, doc, ifcond, values, prefix):
> + def __init__(self, name, info, doc, ifcond, members, prefix):
> QAPISchemaType.__init__(self, name, info, doc, ifcond)
> - for v in values:
> - assert isinstance(v, QAPISchemaMember)
> - v.set_owner(name)
> + for m in members:
> + assert isinstance(m, QAPISchemaMember)
> + m.set_owner(name)
> assert prefix is None or isinstance(prefix, str)
> - self.values = values
> + self.members = members
> self.prefix = prefix
>
> def check(self, schema):
> seen = {}
> - for v in self.values:
> - v.check_clash(self.info, seen)
> + for m in self.members:
> + m.check_clash(self.info, seen)
> if self.doc:
> - self.doc.connect_member(v)
> + self.doc.connect_member(m)
>
> def is_implicit(self):
> # See QAPISchema._make_implicit_enum_type() and ._def_predefineds()
> @@ -1151,14 +1151,14 @@ class QAPISchemaEnumType(QAPISchemaType):
> return c_name(self.name)
>
> def member_names(self):
> - return [v.name for v in self.values]
> + return [m.name for m in self.members]
>
> def json_type(self):
> return 'string'
>
> def visit(self, visitor):
> visitor.visit_enum_type(self.name, self.info, self.ifcond,
> - self.member_names(), self.prefix)
> + self.members, self.prefix)
>
>
> class QAPISchemaArrayType(QAPISchemaType):
> @@ -1952,19 +1952,19 @@ def ifcond_decorator(func):
> return func_wrapper
>
>
> -def gen_enum_lookup(name, values, prefix=None):
> +def gen_enum_lookup(name, members, prefix=None):
> ret = mcgen('''
>
> const QEnumLookup %(c_name)s_lookup = {
> .array = (const char *const[]) {
> ''',
> c_name=c_name(name))
> - for value in values:
> - index = c_enum_const(name, value, prefix)
> + for m in members:
> + index = c_enum_const(name, m.name, prefix)
> ret += mcgen('''
> - [%(index)s] = "%(value)s",
> + [%(index)s] = "%(name)s",
> ''',
> - index=index, value=value)
> + index=index, name=m.name)
>
> ret += mcgen('''
> },
> @@ -1975,9 +1975,9 @@ const QEnumLookup %(c_name)s_lookup = {
> return ret
>
>
> -def gen_enum(name, values, prefix=None):
> +def gen_enum(name, members, prefix=None):
> # append automatically generated _MAX value
> - enum_values = values + ['_MAX']
> + enum_members = members + [QAPISchemaMember('_MAX')]
>
> ret = mcgen('''
>
> @@ -1985,11 +1985,11 @@ typedef enum %(c_name)s {
> ''',
> c_name=c_name(name))
>
> - for value in enum_values:
> + for m in enum_members:
> ret += mcgen('''
> %(c_enum)s,
> ''',
> - c_enum=c_enum_const(name, value, prefix))
> + c_enum=c_enum_const(name, m.name, prefix))
>
> ret += mcgen('''
> } %(c_name)s;
> diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py
> index bef301dfe9..38f4264817 100644
> --- a/scripts/qapi-event.py
> +++ b/scripts/qapi-event.py
> @@ -168,7 +168,7 @@ class QAPISchemaGenEventVisitor(QAPISchemaVisitor):
> def visit_event(self, name, info, ifcond, arg_type, boxed):
> self.decl += gen_event_send_decl(name, arg_type, boxed)
> self.defn += gen_event_send(name, arg_type, boxed)
> - self._event_names.append(name)
> + self._event_names.append(QAPISchemaMember(name))
>
>
> (input_file, output_dir, do_c, do_h, prefix, dummy) = parse_command_line()
> diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
> index 69d9afc792..32a58cf879 100644
> --- a/scripts/qapi-introspect.py
> +++ b/scripts/qapi-introspect.py
> @@ -151,8 +151,9 @@ const QLitObject %(c_name)s = %(c_string)s;
> def visit_builtin_type(self, name, info, json_type):
> self._gen_qlit(name, 'builtin', {'json-type': json_type}, None)
>
> - def visit_enum_type(self, name, info, ifcond, values, prefix):
> - self._gen_qlit(name, 'enum', {'values': values}, ifcond)
> + def visit_enum_type(self, name, info, ifcond, members, prefix):
> + self._gen_qlit(name, 'enum',
> + {'values': [m.name for m in members]}, ifcond)
>
> def visit_array_type(self, name, info, ifcond, element_type):
> element = self._use_type(element_type)
> diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
> index 789e89ff59..75c1823e44 100644
> --- a/scripts/qapi-types.py
> +++ b/scripts/qapi-types.py
> @@ -203,16 +203,16 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
> self.defn += gen_type_cleanup(name)
>
> @ifcond_decorator
> - def visit_enum_type(self, name, info, ifcond, values, prefix):
> + def visit_enum_type(self, name, info, ifcond, members, prefix):
> # Special case for our lone builtin enum type
> # TODO use something cleaner than existence of info
> if not info:
> - self._btin += gen_enum(name, values, prefix)
> + self._btin += gen_enum(name, members, prefix)
> if do_builtins:
> - self.defn += gen_enum_lookup(name, values, prefix)
> + self.defn += gen_enum_lookup(name, members, prefix)
> else:
> - self._fwdecl += gen_enum(name, values, prefix)
> - self.defn += gen_enum_lookup(name, values, prefix)
> + self._fwdecl += gen_enum(name, members, prefix)
> + self.defn += gen_enum_lookup(name, members, prefix)
>
> @ifcond_decorator
> def visit_array_type(self, name, info, ifcond, element_type):
> diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
> index 4b0e005437..7e816ae98e 100644
> --- a/scripts/qapi-visit.py
> +++ b/scripts/qapi-visit.py
> @@ -284,7 +284,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
> self._btin = None
>
> @ifcond_decorator
> - def visit_enum_type(self, name, info, ifcond, values, prefix):
> + def visit_enum_type(self, name, info, ifcond, members, prefix):
> # Special case for our lone builtin enum type
> # TODO use something cleaner than existence of info
> if not info:
> diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py
> index cf63cb0006..e72e7cfe0b 100755
> --- a/scripts/qapi2texi.py
> +++ b/scripts/qapi2texi.py
> @@ -207,7 +207,7 @@ class QAPISchemaGenDocVisitor(qapi.QAPISchemaVisitor):
> def visit_begin(self, schema):
> self.out = ''
>
> - def visit_enum_type(self, name, info, ifcond, values, prefix):
> + def visit_enum_type(self, name, info, ifcond, members, prefix):
> doc = self.cur_doc
> if self.out:
> self.out += '\n'
> diff --git a/tests/qapi-schema/comments.out b/tests/qapi-schema/comments.out
> index 17e652535c..17b493ec24 100644
> --- a/tests/qapi-schema/comments.out
> +++ b/tests/qapi-schema/comments.out
> @@ -1,4 +1,14 @@
> -enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
> +enum QType
> prefix QTYPE
> -enum Status ['good', 'bad', 'ugly']
> + member none:
> + member qnull:
> + member qnum:
> + member qstring:
> + member qdict:
> + member qlist:
> + member qbool:
> +enum Status
> + member good:
> + member bad:
> + member ugly:
> object q_empty
> diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out
> index 63ca25a8b9..0de06ce345 100644
> --- a/tests/qapi-schema/doc-good.out
> +++ b/tests/qapi-schema/doc-good.out
> @@ -1,19 +1,30 @@
> object Base
> member base1: Enum optional=False
> -enum Enum ['one', 'two']
> +enum Enum
> + member one:
> + member two:
> object Object
> base Base
> tag base1
> case one: Variant1
> case two: Variant2
> -enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
> +enum QType
> prefix QTYPE
> + member none:
> + member qnull:
> + member qnum:
> + member qstring:
> + member qdict:
> + member qlist:
> + member qbool:
> object SugaredUnion
> member type: SugaredUnionKind optional=False
> tag type
> case one: q_obj_Variant1-wrapper
> case two: q_obj_Variant2-wrapper
> -enum SugaredUnionKind ['one', 'two']
> +enum SugaredUnionKind
> + member one:
> + member two:
> object Variant1
> member var1: str optional=False
> object Variant2
> diff --git a/tests/qapi-schema/empty.out b/tests/qapi-schema/empty.out
> index 40b886ddae..9859251087 100644
> --- a/tests/qapi-schema/empty.out
> +++ b/tests/qapi-schema/empty.out
> @@ -1,3 +1,10 @@
> -enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
> +enum QType
> prefix QTYPE
> + member none:
> + member qnull:
> + member qnum:
> + member qstring:
> + member qdict:
> + member qlist:
> + member qbool:
> object q_empty
> diff --git a/tests/qapi-schema/event-case.out b/tests/qapi-schema/event-case.out
> index 313c0fe7be..4dccc8f61e 100644
> --- a/tests/qapi-schema/event-case.out
> +++ b/tests/qapi-schema/event-case.out
> @@ -1,5 +1,12 @@
> -enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
> +enum QType
> prefix QTYPE
> + member none:
> + member qnull:
> + member qnum:
> + member qstring:
> + member qdict:
> + member qlist:
> + member qbool:
> event oops None
> boxed=False
> object q_empty
> diff --git a/tests/qapi-schema/ident-with-escape.out b/tests/qapi-schema/ident-with-escape.out
> index b5637cb2e0..4d17bc6783 100644
> --- a/tests/qapi-schema/ident-with-escape.out
> +++ b/tests/qapi-schema/ident-with-escape.out
> @@ -1,5 +1,12 @@
> -enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
> +enum QType
> prefix QTYPE
> + member none:
> + member qnull:
> + member qnum:
> + member qstring:
> + member qdict:
> + member qlist:
> + member qbool:
> command fooA q_obj_fooA-arg -> None
> gen=True success_response=True boxed=False
> object q_empty
> diff --git a/tests/qapi-schema/include-relpath.out b/tests/qapi-schema/include-relpath.out
> index 17e652535c..17b493ec24 100644
> --- a/tests/qapi-schema/include-relpath.out
> +++ b/tests/qapi-schema/include-relpath.out
> @@ -1,4 +1,14 @@
> -enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
> +enum QType
> prefix QTYPE
> -enum Status ['good', 'bad', 'ugly']
> + member none:
> + member qnull:
> + member qnum:
> + member qstring:
> + member qdict:
> + member qlist:
> + member qbool:
> +enum Status
> + member good:
> + member bad:
> + member ugly:
> object q_empty
> diff --git a/tests/qapi-schema/include-repetition.out b/tests/qapi-schema/include-repetition.out
> index 17e652535c..17b493ec24 100644
> --- a/tests/qapi-schema/include-repetition.out
> +++ b/tests/qapi-schema/include-repetition.out
> @@ -1,4 +1,14 @@
> -enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
> +enum QType
> prefix QTYPE
> -enum Status ['good', 'bad', 'ugly']
> + member none:
> + member qnull:
> + member qnum:
> + member qstring:
> + member qdict:
> + member qlist:
> + member qbool:
> +enum Status
> + member good:
> + member bad:
> + member ugly:
> object q_empty
> diff --git a/tests/qapi-schema/include-simple.out b/tests/qapi-schema/include-simple.out
> index 17e652535c..17b493ec24 100644
> --- a/tests/qapi-schema/include-simple.out
> +++ b/tests/qapi-schema/include-simple.out
> @@ -1,4 +1,14 @@
> -enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
> +enum QType
> prefix QTYPE
> -enum Status ['good', 'bad', 'ugly']
> + member none:
> + member qnull:
> + member qnum:
> + member qstring:
> + member qdict:
> + member qlist:
> + member qbool:
> +enum Status
> + member good:
> + member bad:
> + member ugly:
> object q_empty
> diff --git a/tests/qapi-schema/indented-expr.out b/tests/qapi-schema/indented-expr.out
> index 586795f44d..8bdc016e55 100644
> --- a/tests/qapi-schema/indented-expr.out
> +++ b/tests/qapi-schema/indented-expr.out
> @@ -1,5 +1,12 @@
> -enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
> +enum QType
> prefix QTYPE
> + member none:
> + member qnull:
> + member qnum:
> + member qstring:
> + member qdict:
> + member qlist:
> + member qbool:
> command eins None -> None
> gen=True success_response=True boxed=False
> object q_empty
> diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
> index fc5fd25f1b..9a7cafc269 100644
> --- a/tests/qapi-schema/qapi-schema-test.out
> +++ b/tests/qapi-schema/qapi-schema-test.out
> @@ -33,7 +33,10 @@ event EVENT_F UserDefAlternate
> object Empty1
> object Empty2
> base Empty1
> -enum EnumOne ['value1', 'value2', 'value3']
> +enum EnumOne
> + member value1:
> + member value2:
> + member value3:
> object EventStructOne
> member struct1: UserDefOne optional=False
> member string: str optional=False
> @@ -42,16 +45,25 @@ object ForceArrays
> member unused1: UserDefOneList optional=False
> member unused2: UserDefTwoList optional=False
> member unused3: TestStructList optional=False
> -enum MyEnum []
> +enum MyEnum
> object NestedEnumsOne
> member enum1: EnumOne optional=False
> member enum2: EnumOne optional=True
> member enum3: EnumOne optional=False
> member enum4: EnumOne optional=True
> -enum QEnumTwo ['value1', 'value2']
> +enum QEnumTwo
> prefix QENUM_TWO
> -enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
> + member value1:
> + member value2:
> +enum QType
> prefix QTYPE
> + member none:
> + member qnull:
> + member qnum:
> + member qstring:
> + member qdict:
> + member qlist:
> + member qbool:
> alternate TestIfAlternate
> tag type
> case foo: int
> @@ -60,7 +72,9 @@ alternate TestIfAlternate
> command TestIfCmd q_obj_TestIfCmd-arg -> None
> gen=True success_response=True boxed=False
> if defined(TEST_IF_CMD) && defined(TEST_IF_STRUCT)
> -enum TestIfEnum ['foo', 'bar']
> +enum TestIfEnum
> + member foo:
> + member bar:
> if defined(TEST_IF_ENUM)
> event TestIfEvent q_obj_TestIfEvent-arg
> boxed=False
> @@ -73,7 +87,8 @@ object TestIfUnion
> tag type
> case foo: q_obj_TestStruct-wrapper
> if defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)
> -enum TestIfUnionKind ['foo']
> +enum TestIfUnionKind
> + member foo:
> if defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)
> object TestStruct
> member integer: int optional=False
> @@ -122,7 +137,21 @@ object UserDefNativeListUnion
> case string: q_obj_strList-wrapper
> case sizes: q_obj_sizeList-wrapper
> case any: q_obj_anyList-wrapper
> -enum UserDefNativeListUnionKind ['integer', 's8', 's16', 's32', 's64', 'u8', 'u16', 'u32', 'u64', 'number', 'boolean', 'string', 'sizes', 'any']
> +enum UserDefNativeListUnionKind
> + member integer:
> + member s8:
> + member s16:
> + member s32:
> + member s64:
> + member u8:
> + member u16:
> + member u32:
> + member u64:
> + member number:
> + member boolean:
> + member string:
> + member sizes:
> + member any:
> object UserDefOne
> base UserDefZero
> member string: str optional=False
> @@ -159,7 +188,8 @@ alternate __org.qemu_x-Alt
> case b: __org.qemu_x-Base
> object __org.qemu_x-Base
> member __org.qemu_x-member1: __org.qemu_x-Enum optional=False
> -enum __org.qemu_x-Enum ['__org.qemu_x-value']
> +enum __org.qemu_x-Enum
> + member __org.qemu_x-value:
> object __org.qemu_x-Struct
> base __org.qemu_x-Base
> member __org.qemu_x-member2: str optional=False
> @@ -170,7 +200,8 @@ object __org.qemu_x-Union1
> member type: __org.qemu_x-Union1Kind optional=False
> tag type
> case __org.qemu_x-branch: q_obj_str-wrapper
> -enum __org.qemu_x-Union1Kind ['__org.qemu_x-branch']
> +enum __org.qemu_x-Union1Kind
> + member __org.qemu_x-branch:
> object __org.qemu_x-Union2
> base __org.qemu_x-Base
> tag __org.qemu_x-member1
> diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
> index 8627f978af..67c6c1ecef 100644
> --- a/tests/qapi-schema/test-qapi.py
> +++ b/tests/qapi-schema/test-qapi.py
> @@ -17,19 +17,18 @@ import sys
>
>
> class QAPISchemaTestVisitor(QAPISchemaVisitor):
> - def visit_enum_type(self, name, info, ifcond, values, prefix):
> - print 'enum %s %s' % (name, values)
> + def visit_enum_type(self, name, info, ifcond, members, prefix):
> + print 'enum %s' % name
> if prefix:
> print ' prefix %s' % prefix
> + self._print_members(members)
> self._print_if(ifcond)
>
> def visit_object_type(self, name, info, ifcond, base, members, variants):
> print 'object %s' % name
> if base:
> print ' base %s' % base.name
> - for m in members:
> - print ' member %s: %s optional=%s' % \
> - (m.name, m.type.name, m.optional)
> + self._print_members(members)
> self._print_variants(variants)
> self._print_if(ifcond)
>
> @@ -51,6 +50,14 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
> print ' boxed=%s' % boxed
> self._print_if(ifcond)
>
> + @staticmethod
> + def _print_members(members):
> + for m in members:
> + print ' member %s:' % m.name,
> + if isinstance(m, QAPISchemaObjectTypeMember):
> + print '%s optional=%s' % (m.type.name, m.optional),
> + print
> +
> @staticmethod
> def _print_variants(variants):
> if variants:
The change advertized in the commit message is hard to see among all the
other stuff going on. I think this patch should be split into three
parts:
1. Rename QAPISchemaEnumType.values and related variables to members.
Makes sense ever since commit 93bda4dd4 changed .values from list of
string to list of QAPISchemaMember. Obvious no-op.
2. Change the visit_enum_type().
3. Change test-qapi.py.
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 17/50] qapi: do not define enumeration value explicitely
2017-12-07 17:01 ` Marc-André Lureau
@ 2017-12-08 7:50 ` Markus Armbruster
2018-01-11 21:24 ` Marc-André Lureau
0 siblings, 1 reply; 118+ messages in thread
From: Markus Armbruster @ 2017-12-08 7:50 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: QEMU, Michael Roth
Marc-André Lureau <marcandre.lureau@gmail.com> writes:
> On Thu, Dec 7, 2017 at 5:23 PM, Markus Armbruster <armbru@redhat.com> wrote:
>> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>>
>>> The C standard has the initial value at 0 and the subsequent values
>>> incremented by 1. No need to set this explicitely.
>>>
>>> This will prevent from artificial "gaps" when compiling out some enum
>>> values and having unnecessarily large MAX values & enums arrays.
>>>
>>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>>> ---
>>> scripts/qapi.py | 7 ++-----
>>> 1 file changed, 2 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/scripts/qapi.py b/scripts/qapi.py
>>> index 94b735d8d6..074ee221a1 100644
>>> --- a/scripts/qapi.py
>>> +++ b/scripts/qapi.py
>>> @@ -1985,14 +1985,11 @@ typedef enum %(c_name)s {
>>> ''',
>>> c_name=c_name(name))
>>>
>>> - i = 0
>>> for value in enum_values:
>>> ret += mcgen('''
>>> - %(c_enum)s = %(i)d,
>>> + %(c_enum)s,
>>> ''',
>>> - c_enum=c_enum_const(name, value, prefix),
>>> - i=i)
>>> - i += 1
>>> + c_enum=c_enum_const(name, value, prefix))
>>>
>>> ret += mcgen('''
>>> } %(c_name)s;
>>
>> Recapitulate review of v2: this risks entertaining mishaps like
>> compiling this one
>>
>> typedef enum Color {
>> COLOR_WHITE,
>> #if defined(NEED_CPU_H)
>> #if defined(TARGET_S390X)
>> COLOR_BLUE,
>> #endif /* defined(TARGET_S390X) */
>> #endif /* defined(NEED_CPU_H) */
>> COLOR_BLACK,
>> } Color;
>>
>> in s390x-code (COLOR_BLACK = 2) and in target-independent code
>> (COLOR_BLACK = 1), then linking the two together.
>>
>> Same issue for struct members and such (previous patch).
>>
>> What's our story on preventing disaster here?
>>
>> In the long run, we want to split the generated code so that
>> target-specific and target-independent code are separate, and each part
>> is always compiled with consistent preprocessor symbols. But I'm afraid
>> that's not in the card right now.
>
> Eh, I need to refresh my memories about that series, but I think
> that's what I did in v3
>
> It doesn't use the NEED_CPU_H trick. It has a seperate per-target target.json
Looking... aha! target.json appears in PATCH 44 (which I haven't even
glanced at, yet). The problem appears in PATCH 16, though. Perhaps a
bit of patch reshuffling would do.
>> I therefore proposed the stupidest temporary stopgap that could possibly
>> work: apply conditionals *only* to qmp-introspect.c, leave everything
>> unconditional elsewhere.
>
> I don't like that idea much and I don't think we need that
> restriction, but I need to get back to that series on some point
> (probably after you finish the review).
It's a beefy series, and it's probably best to let me review the largest
prefix I can before we dive into discussion.
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 19/50] qapi: add 'if' to enum members
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 19/50] qapi: add 'if' to enum members Marc-André Lureau
@ 2017-12-08 8:38 ` Markus Armbruster
2018-01-11 21:24 ` Marc-André Lureau
0 siblings, 1 reply; 118+ messages in thread
From: Markus Armbruster @ 2017-12-08 8:38 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Michael Roth
A bit more detail in the commit message would make this patch easier to
review.
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi.py | 39 ++++++++++++++++++++++++++++-----
> tests/Makefile.include | 1 -
> tests/qapi-schema/enum-dict-member.err | 1 -
> tests/qapi-schema/enum-dict-member.exit | 1 -
> tests/qapi-schema/enum-dict-member.json | 2 --
> tests/qapi-schema/enum-dict-member.out | 0
> tests/qapi-schema/qapi-schema-test.json | 5 +++--
> tests/qapi-schema/qapi-schema-test.out | 3 ++-
> tests/qapi-schema/test-qapi.py | 2 ++
> 9 files changed, 41 insertions(+), 13 deletions(-)
> delete mode 100644 tests/qapi-schema/enum-dict-member.err
> delete mode 100644 tests/qapi-schema/enum-dict-member.exit
> delete mode 100644 tests/qapi-schema/enum-dict-member.json
> delete mode 100644 tests/qapi-schema/enum-dict-member.out
>
> diff --git a/scripts/qapi.py b/scripts/qapi.py
> index 386a577a59..1535de9ce7 100644
> --- a/scripts/qapi.py
> +++ b/scripts/qapi.py
> @@ -659,6 +659,14 @@ def check_if(expr, info):
> info, "'if' condition must be a string or a list of strings")
>
>
> +def check_unknown_keys(info, dict, allowed_keys):
> + diff = set(dict) - allowed_keys
> + if not diff:
> + return
> + raise QAPISemError(info, "Dictionnary has unknown keys: %s (allowed: %s)" %
s/Dictionnary/Dictionary/
> + (', '.join(diff), ', '.join(allowed_keys)))
I'm afraid this duplicates a part of check_keys(). Could it be factored
out?
> +
> +
> def check_type(info, source, value, allow_array=False,
> allow_dict=False, allow_optional=False,
> allow_metas=[]):
> @@ -739,6 +747,10 @@ def check_event(expr, info):
> allow_metas=meta)
>
>
> +def enum_get_values(expr):
> + return [e if isinstance(e, str) else e['name'] for e in expr['data']]
> +
> +
> def check_union(expr, info):
> name = expr['union']
> base = expr.get('base')
> @@ -798,7 +810,7 @@ def check_union(expr, info):
> # If the discriminator names an enum type, then all members
> # of 'data' must also be members of the enum type.
> if enum_define:
> - if key not in enum_define['data']:
> + if key not in enum_get_values(enum_define):
> raise QAPISemError(info,
> "Discriminator value '%s' is not found in "
> "enum '%s'"
> @@ -806,7 +818,7 @@ def check_union(expr, info):
>
> # If discriminator is user-defined, ensure all values are covered
> if enum_define:
> - for value in enum_define['data']:
> + for value in enum_get_values(enum_define):
> if value not in members.keys():
> raise QAPISemError(info, "Union '%s' data missing '%s' branch"
> % (name, value))
> @@ -837,7 +849,7 @@ def check_alternate(expr, info):
> if qtype == 'QTYPE_QSTRING':
> enum_expr = enum_types.get(value)
> if enum_expr:
> - for v in enum_expr['data']:
> + for v in enum_get_values(enum_expr):
> if v in ['on', 'off']:
> conflicting.add('QTYPE_QBOOL')
> if re.match(r'[-+0-9.]', v): # lazy, could be tightened
> @@ -865,6 +877,14 @@ def check_enum(expr, info):
> raise QAPISemError(info,
> "Enum '%s' requires a string for 'prefix'" % name)
> for member in members:
> + if isinstance(member, dict):
> + if 'name' not in member:
> + raise QAPISemError(info, "Dictionary member of enum '%s' must "
> + "have a 'name' key" % name)
> + if 'if' in member:
> + check_if(member, info)
> + check_unknown_keys(info, member, {'name', 'if'})
> + member = member['name']
> check_name(info, "Member of enum '%s'" % name, member,
> enum_member=True)
>
> @@ -1280,9 +1300,11 @@ class QAPISchemaObjectType(QAPISchemaType):
> class QAPISchemaMember(object):
> role = 'member'
>
> - def __init__(self, name):
> + def __init__(self, name, ifcond=None):
> assert isinstance(name, str)
> + assert ifcond is None or isinstance(ifcond, str)
> self.name = name
> + self.ifcond = ifcond
> self.owner = None
>
> def set_owner(self, name):
QAPISchemaObjectTypeMember inherits .ifcond. Peeking ahead: looks like
it'll get used when we add conditions to object type members, PATCH
23ff. Okay. Mentioning it in the commit message wouldn't hurt, though.
> @@ -1559,7 +1581,14 @@ class QAPISchema(object):
> qtype_values, 'QTYPE'))
>
> def _make_enum_members(self, values):
> - return [QAPISchemaMember(v) for v in values]
> + enum = []
> + for v in values:
> + ifcond = None
> + if isinstance(v, dict):
> + ifcond = v.get('if')
> + v = v['name']
> + enum.append(QAPISchemaMember(v, ifcond))
I like brevity a lot, but if it's bought by assigning to a loop control
variable, I pass. Cleaner:
for v in values:
if isinstance(v, dict):
name = v['name']
ifcond = v.get('if')
else:
name = v
ifcond = None
enum.append(QAPISchemaMember(name, ifcond))
> + return enum
>
> def _make_implicit_enum_type(self, name, info, ifcond, values):
> # See also QAPISchemaObjectTypeMember._pretty_owner()
> diff --git a/tests/Makefile.include b/tests/Makefile.include
> index 8dac7c9083..a9f0ddbe01 100644
> --- a/tests/Makefile.include
> +++ b/tests/Makefile.include
> @@ -443,7 +443,6 @@ qapi-schema += empty.json
> qapi-schema += enum-bad-name.json
> qapi-schema += enum-bad-prefix.json
> qapi-schema += enum-clash-member.json
> -qapi-schema += enum-dict-member.json
> qapi-schema += enum-int-member.json
> qapi-schema += enum-member-case.json
> qapi-schema += enum-missing-data.json
> diff --git a/tests/qapi-schema/enum-dict-member.err b/tests/qapi-schema/enum-dict-member.err
> deleted file mode 100644
> index 8ca146ea59..0000000000
> --- a/tests/qapi-schema/enum-dict-member.err
> +++ /dev/null
> @@ -1 +0,0 @@
> -tests/qapi-schema/enum-dict-member.json:2: Member of enum 'MyEnum' requires a string name
> diff --git a/tests/qapi-schema/enum-dict-member.exit b/tests/qapi-schema/enum-dict-member.exit
> deleted file mode 100644
> index d00491fd7e..0000000000
> --- a/tests/qapi-schema/enum-dict-member.exit
> +++ /dev/null
> @@ -1 +0,0 @@
> -1
> diff --git a/tests/qapi-schema/enum-dict-member.json b/tests/qapi-schema/enum-dict-member.json
> deleted file mode 100644
> index 79672e0f09..0000000000
> --- a/tests/qapi-schema/enum-dict-member.json
> +++ /dev/null
> @@ -1,2 +0,0 @@
> -# we reject any enum member that is not a string
> -{ 'enum': 'MyEnum', 'data': [ { 'value': 'str' } ] }
> diff --git a/tests/qapi-schema/enum-dict-member.out b/tests/qapi-schema/enum-dict-member.out
> deleted file mode 100644
> index e69de29bb2..0000000000
Hmm. The dict instance of "enum value must be of an appropriate JSON
type" error class goes away in this patch, but the class remains. Do we
still cover it?
There's enum-int-member.json, but it's not a good test: it dies in the
lexer. I think we should replace the two tests by a single one.
Perhaps something like 'data': [ [] ] would do.
> diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
> index dc2c444fc1..ad2b405d83 100644
> --- a/tests/qapi-schema/qapi-schema-test.json
> +++ b/tests/qapi-schema/qapi-schema-test.json
> @@ -194,7 +194,8 @@
> { 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
> 'if': 'defined(TEST_IF_STRUCT)' }
>
> -{ 'enum': 'TestIfEnum', 'data': [ 'foo', 'bar' ],
> +{ 'enum': 'TestIfEnum', 'data':
> + [ 'foo', { 'name' : 'bar', 'if': 'defined(TEST_IF_ENUM_BAR)' } ],
> 'if': 'defined(TEST_IF_ENUM)' }
>
> { 'union': 'TestIfUnion', 'data': { 'foo': 'TestStruct' },
> @@ -203,7 +204,7 @@
> { 'alternate': 'TestIfAlternate', 'data': { 'foo': 'int', 'bar': 'TestStruct' },
> 'if': 'defined(TEST_IF_ALT) && defined(TEST_IF_STRUCT)' }
>
> -{ 'command': 'TestIfCmd', 'data': { 'foo': 'TestIfStruct' },
> +{ 'command': 'TestIfCmd', 'data': { 'foo': 'TestIfStruct', 'bar': 'TestIfEnum' },
> 'if': 'defined(TEST_IF_CMD) && defined(TEST_IF_STRUCT)' }
>
> { 'event': 'TestIfEvent', 'data': { 'foo': 'TestIfStruct' },
Should this hunk be in PATCH 04?
> diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
> index 9a7cafc269..8a0cf1a551 100644
> --- a/tests/qapi-schema/qapi-schema-test.out
> +++ b/tests/qapi-schema/qapi-schema-test.out
> @@ -74,7 +74,7 @@ command TestIfCmd q_obj_TestIfCmd-arg -> None
> if defined(TEST_IF_CMD) && defined(TEST_IF_STRUCT)
> enum TestIfEnum
> member foo:
> - member bar:
> + member bar: if=defined(TEST_IF_ENUM_BAR)
> if defined(TEST_IF_ENUM)
> event TestIfEvent q_obj_TestIfEvent-arg
> boxed=False
> @@ -228,6 +228,7 @@ object q_obj_EVENT_D-arg
> member enum3: EnumOne optional=True
> object q_obj_TestIfCmd-arg
> member foo: TestIfStruct optional=False
> + member bar: TestIfEnum optional=False
> if defined(TEST_IF_CMD) && defined(TEST_IF_STRUCT)
> object q_obj_TestIfEvent-arg
> member foo: TestIfStruct optional=False
> diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
> index 67c6c1ecef..a86c3b5ee1 100644
> --- a/tests/qapi-schema/test-qapi.py
> +++ b/tests/qapi-schema/test-qapi.py
> @@ -56,6 +56,8 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
> print ' member %s:' % m.name,
> if isinstance(m, QAPISchemaObjectTypeMember):
> print '%s optional=%s' % (m.type.name, m.optional),
> + if m.ifcond:
> + print 'if=%s' % m.ifcond,
> print
>
> @staticmethod
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 20/50] qapi-event: add 'if' condition to generated enum
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 20/50] qapi-event: add 'if' condition to generated enum Marc-André Lureau
@ 2017-12-08 13:58 ` Markus Armbruster
2017-12-08 14:07 ` Markus Armbruster
0 siblings, 1 reply; 118+ messages in thread
From: Markus Armbruster @ 2017-12-08 13:58 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Michael Roth
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Add condition to QAPIEvent enum members based on the event 'if'.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi-event.py | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py
> index 38f4264817..60c6f7030d 100644
> --- a/scripts/qapi-event.py
> +++ b/scripts/qapi-event.py
> @@ -168,7 +168,7 @@ class QAPISchemaGenEventVisitor(QAPISchemaVisitor):
> def visit_event(self, name, info, ifcond, arg_type, boxed):
> self.decl += gen_event_send_decl(name, arg_type, boxed)
> self.defn += gen_event_send(name, arg_type, boxed)
> - self._event_names.append(QAPISchemaMember(name))
> + self._event_names.append(QAPISchemaMember(name, ifcond))
>
>
> (input_file, output_dir, do_c, do_h, prefix, dummy) = parse_command_line()
No test coverage?
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 20/50] qapi-event: add 'if' condition to generated enum
2017-12-08 13:58 ` Markus Armbruster
@ 2017-12-08 14:07 ` Markus Armbruster
2018-01-11 21:31 ` Marc-André Lureau
0 siblings, 1 reply; 118+ messages in thread
From: Markus Armbruster @ 2017-12-08 14:07 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Michael Roth
Markus Armbruster <armbru@redhat.com> writes:
> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>
>> Add condition to QAPIEvent enum members based on the event 'if'.
>>
>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>> ---
>> scripts/qapi-event.py | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py
>> index 38f4264817..60c6f7030d 100644
>> --- a/scripts/qapi-event.py
>> +++ b/scripts/qapi-event.py
>> @@ -168,7 +168,7 @@ class QAPISchemaGenEventVisitor(QAPISchemaVisitor):
>> def visit_event(self, name, info, ifcond, arg_type, boxed):
>> self.decl += gen_event_send_decl(name, arg_type, boxed)
>> self.defn += gen_event_send(name, arg_type, boxed)
>> - self._event_names.append(QAPISchemaMember(name))
>> + self._event_names.append(QAPISchemaMember(name, ifcond))
>>
>>
>> (input_file, output_dir, do_c, do_h, prefix, dummy) = parse_command_line()
>
> No test coverage?
Wait! This patch has no effect, because the it merely puts the ifcond
argument into QAPISchemaMember.ifcond. Only later patches put
QAPISchemaMember.ifcond to use. Correct?
Aside: the ifcond_decorator could already be doing something with the
argument, but I'll be hanged if I remember how that magic works.
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 22/50] tests: add some enum members tests
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 22/50] tests: add some enum members tests Marc-André Lureau
@ 2017-12-08 17:58 ` Markus Armbruster
0 siblings, 0 replies; 118+ messages in thread
From: Markus Armbruster @ 2017-12-08 17:58 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Michael Roth
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> tests/Makefile.include | 3 +++
> tests/qapi-schema/enum-dict-member-invalid.err | 1 +
> tests/qapi-schema/enum-dict-member-invalid.exit | 1 +
> tests/qapi-schema/enum-dict-member-invalid.json | 2 ++
> tests/qapi-schema/enum-dict-member-invalid.out | 0
> tests/qapi-schema/enum-dict-member-invalid2.err | 1 +
> tests/qapi-schema/enum-dict-member-invalid2.exit | 1 +
> tests/qapi-schema/enum-dict-member-invalid2.json | 2 ++
> tests/qapi-schema/enum-dict-member-invalid2.out | 0
> tests/qapi-schema/enum-if-invalid.err | 1 +
> tests/qapi-schema/enum-if-invalid.exit | 1 +
> tests/qapi-schema/enum-if-invalid.json | 3 +++
> tests/qapi-schema/enum-if-invalid.out | 0
> 13 files changed, 16 insertions(+)
> create mode 100644 tests/qapi-schema/enum-dict-member-invalid.err
> create mode 100644 tests/qapi-schema/enum-dict-member-invalid.exit
> create mode 100644 tests/qapi-schema/enum-dict-member-invalid.json
> create mode 100644 tests/qapi-schema/enum-dict-member-invalid.out
> create mode 100644 tests/qapi-schema/enum-dict-member-invalid2.err
> create mode 100644 tests/qapi-schema/enum-dict-member-invalid2.exit
> create mode 100644 tests/qapi-schema/enum-dict-member-invalid2.json
> create mode 100644 tests/qapi-schema/enum-dict-member-invalid2.out
> create mode 100644 tests/qapi-schema/enum-if-invalid.err
> create mode 100644 tests/qapi-schema/enum-if-invalid.exit
> create mode 100644 tests/qapi-schema/enum-if-invalid.json
> create mode 100644 tests/qapi-schema/enum-if-invalid.out
>
> diff --git a/tests/Makefile.include b/tests/Makefile.include
> index a9f0ddbe01..0aa532f029 100644
> --- a/tests/Makefile.include
> +++ b/tests/Makefile.include
> @@ -443,6 +443,9 @@ qapi-schema += empty.json
> qapi-schema += enum-bad-name.json
> qapi-schema += enum-bad-prefix.json
> qapi-schema += enum-clash-member.json
> +qapi-schema += enum-dict-member-invalid.json
> +qapi-schema += enum-dict-member-invalid2.json
> +qapi-schema += enum-if-invalid.json
> qapi-schema += enum-int-member.json
> qapi-schema += enum-member-case.json
> qapi-schema += enum-missing-data.json
> diff --git a/tests/qapi-schema/enum-dict-member-invalid.err b/tests/qapi-schema/enum-dict-member-invalid.err
> new file mode 100644
> index 0000000000..d12cca0df3
> --- /dev/null
> +++ b/tests/qapi-schema/enum-dict-member-invalid.err
> @@ -0,0 +1 @@
> +tests/qapi-schema/enum-dict-member-invalid.json:2: Dictionary member of enum 'MyEnum' must have a 'name' key
> diff --git a/tests/qapi-schema/enum-dict-member-invalid.exit b/tests/qapi-schema/enum-dict-member-invalid.exit
> new file mode 100644
> index 0000000000..d00491fd7e
> --- /dev/null
> +++ b/tests/qapi-schema/enum-dict-member-invalid.exit
> @@ -0,0 +1 @@
> +1
> diff --git a/tests/qapi-schema/enum-dict-member-invalid.json b/tests/qapi-schema/enum-dict-member-invalid.json
> new file mode 100644
> index 0000000000..9cf8406867
> --- /dev/null
> +++ b/tests/qapi-schema/enum-dict-member-invalid.json
> @@ -0,0 +1,2 @@
> +# we reject any enum member that is not a string or a dict with 'name'
> +{ 'enum': 'MyEnum', 'data': [ { 'value': 'str' } ] }
> diff --git a/tests/qapi-schema/enum-dict-member-invalid.out b/tests/qapi-schema/enum-dict-member-invalid.out
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/tests/qapi-schema/enum-dict-member-invalid2.err b/tests/qapi-schema/enum-dict-member-invalid2.err
> new file mode 100644
> index 0000000000..f7dc1a2b33
> --- /dev/null
> +++ b/tests/qapi-schema/enum-dict-member-invalid2.err
> @@ -0,0 +1 @@
> +tests/qapi-schema/enum-dict-member-invalid2.json:2: Dictionnary has unknown keys: bad-key (allowed: name, if)
> diff --git a/tests/qapi-schema/enum-dict-member-invalid2.exit b/tests/qapi-schema/enum-dict-member-invalid2.exit
> new file mode 100644
> index 0000000000..d00491fd7e
> --- /dev/null
> +++ b/tests/qapi-schema/enum-dict-member-invalid2.exit
> @@ -0,0 +1 @@
> +1
> diff --git a/tests/qapi-schema/enum-dict-member-invalid2.json b/tests/qapi-schema/enum-dict-member-invalid2.json
> new file mode 100644
> index 0000000000..6664c59201
> --- /dev/null
> +++ b/tests/qapi-schema/enum-dict-member-invalid2.json
> @@ -0,0 +1,2 @@
> +# we reject any enum member that is not a string or a dict with 'name'
> +{ 'enum': 'MyEnum', 'data': [ { 'name': 'foo', 'bad-key': 'str' } ] }
> diff --git a/tests/qapi-schema/enum-dict-member-invalid2.out b/tests/qapi-schema/enum-dict-member-invalid2.out
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/tests/qapi-schema/enum-if-invalid.err b/tests/qapi-schema/enum-if-invalid.err
> new file mode 100644
> index 0000000000..54c3cf887b
> --- /dev/null
> +++ b/tests/qapi-schema/enum-if-invalid.err
> @@ -0,0 +1 @@
> +tests/qapi-schema/enum-if-invalid.json:2: 'if' condition must be a string or a list of strings
> diff --git a/tests/qapi-schema/enum-if-invalid.exit b/tests/qapi-schema/enum-if-invalid.exit
> new file mode 100644
> index 0000000000..d00491fd7e
> --- /dev/null
> +++ b/tests/qapi-schema/enum-if-invalid.exit
> @@ -0,0 +1 @@
> +1
> diff --git a/tests/qapi-schema/enum-if-invalid.json b/tests/qapi-schema/enum-if-invalid.json
> new file mode 100644
> index 0000000000..60bd0ef1d7
> --- /dev/null
> +++ b/tests/qapi-schema/enum-if-invalid.json
> @@ -0,0 +1,3 @@
> +# check invalid 'if' type
> +{ 'enum': 'TestIfEnum', 'data':
> + [ 'foo', { 'name' : 'bar', 'if': { 'val': 'foo' } } ] }
> diff --git a/tests/qapi-schema/enum-if-invalid.out b/tests/qapi-schema/enum-if-invalid.out
> new file mode 100644
> index 0000000000..e69de29bb2
These tests are related to the coverage gap I mentioned in my review of
PATCH 19.
I think it makes sense to add related new tests together, right when we
add whatever they test.
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 23/50] qapi: add 'if' to struct members and implicit objects members
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 23/50] qapi: add 'if' to struct members and implicit objects members Marc-André Lureau
@ 2017-12-09 8:18 ` Markus Armbruster
0 siblings, 0 replies; 118+ messages in thread
From: Markus Armbruster @ 2017-12-09 8:18 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Michael Roth
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> check_type() will now accept a DICT { 'type': TYPENAME, 'if': ... }
> instead of a TYPENAME. This is the case in various situations where
> implicit object types are allowed such as commands/events arguments
> and return type, base and branches of union & alternate.
Uh, do you mean where implicit object type are *not* allowed?
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi.py | 20 ++++++++++++++++----
> tests/qapi-schema/qapi-schema-test.json | 12 +++++++++---
> tests/qapi-schema/qapi-schema-test.out | 4 +++-
> 3 files changed, 28 insertions(+), 8 deletions(-)
>
> diff --git a/scripts/qapi.py b/scripts/qapi.py
> index df2a304e8f..15711f96fa 100644
> --- a/scripts/qapi.py
> +++ b/scripts/qapi.py
> @@ -696,7 +696,15 @@ def check_type(info, source, value, allow_array=False,
> return
>
> if not allow_dict:
> - raise QAPISemError(info, "%s should be a type name" % source)
> + if isinstance(value, dict) and 'type' in value:
> + check_type(info, source, value['type'], allow_array,
> + allow_dict, allow_optional, allow_metas)
> + if 'if' in value:
> + check_if(value, info)
> + check_unknown_keys(info, value, {'type', 'if'})
> + return
> + else:
> + raise QAPISemError(info, "%s should be a type name" % source)
@allow_dict becomes a misnomer: dictionaries are now always allowed, but
they have different meaning (implicit type vs. named type with
additional attributes).
Rename to @allow_implicit?
>
> if not isinstance(value, OrderedDict):
> raise QAPISemError(info,
[...]
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 24/50] qapi: add some struct member tests
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 24/50] qapi: add some struct member tests Marc-André Lureau
@ 2017-12-09 9:07 ` Markus Armbruster
2018-01-11 21:31 ` Marc-André Lureau
0 siblings, 1 reply; 118+ messages in thread
From: Markus Armbruster @ 2017-12-09 9:07 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Michael Roth
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> tests/Makefile.include | 2 ++
> tests/qapi-schema/struct-if-invalid.err | 1 +
> tests/qapi-schema/struct-if-invalid.exit | 1 +
> tests/qapi-schema/struct-if-invalid.json | 3 +++
> tests/qapi-schema/struct-if-invalid.out | 0
> tests/qapi-schema/struct-member-type.err | 0
> tests/qapi-schema/struct-member-type.exit | 1 +
> tests/qapi-schema/struct-member-type.json | 2 ++
> tests/qapi-schema/struct-member-type.out | 12 ++++++++++++
> 9 files changed, 22 insertions(+)
> create mode 100644 tests/qapi-schema/struct-if-invalid.err
> create mode 100644 tests/qapi-schema/struct-if-invalid.exit
> create mode 100644 tests/qapi-schema/struct-if-invalid.json
> create mode 100644 tests/qapi-schema/struct-if-invalid.out
> create mode 100644 tests/qapi-schema/struct-member-type.err
> create mode 100644 tests/qapi-schema/struct-member-type.exit
> create mode 100644 tests/qapi-schema/struct-member-type.json
> create mode 100644 tests/qapi-schema/struct-member-type.out
>
> diff --git a/tests/Makefile.include b/tests/Makefile.include
> index 0aa532f029..44a3d8895e 100644
> --- a/tests/Makefile.include
> +++ b/tests/Makefile.include
> @@ -520,7 +520,9 @@ qapi-schema += returns-whitelist.json
> qapi-schema += struct-base-clash-deep.json
> qapi-schema += struct-base-clash.json
> qapi-schema += struct-data-invalid.json
> +qapi-schema += struct-if-invalid.json
> qapi-schema += struct-member-invalid.json
> +qapi-schema += struct-member-type.json
> qapi-schema += trailing-comma-list.json
> qapi-schema += trailing-comma-object.json
> qapi-schema += type-bypass-bad-gen.json
> diff --git a/tests/qapi-schema/struct-if-invalid.err b/tests/qapi-schema/struct-if-invalid.err
> new file mode 100644
> index 0000000000..42245262a9
> --- /dev/null
> +++ b/tests/qapi-schema/struct-if-invalid.err
> @@ -0,0 +1 @@
> +tests/qapi-schema/struct-if-invalid.json:2: Member 'bar' of 'data' for struct 'TestIfStruct' should be a type name
> diff --git a/tests/qapi-schema/struct-if-invalid.exit b/tests/qapi-schema/struct-if-invalid.exit
> new file mode 100644
> index 0000000000..d00491fd7e
> --- /dev/null
> +++ b/tests/qapi-schema/struct-if-invalid.exit
> @@ -0,0 +1 @@
> +1
> diff --git a/tests/qapi-schema/struct-if-invalid.json b/tests/qapi-schema/struct-if-invalid.json
> new file mode 100644
> index 0000000000..466cdb61e1
> --- /dev/null
> +++ b/tests/qapi-schema/struct-if-invalid.json
> @@ -0,0 +1,3 @@
> +# check missing 'type'
> +{ 'struct': 'TestIfStruct', 'data':
> + { 'foo': 'int', 'bar': { 'if': 'defined(TEST_IF_STRUCT_BAR)' } } }
Hmm. This tests the previous patch's change to check_type(). It
demonstrates that the "should be a type name" error message can be
suboptimal: it gets triggered when
not isinstance(value, str)
and not (isinstance(value, dict) and 'type' in value)
Fine when the value is neither str not dict. Suboptimal when it's dict
and 'type' is missing. A more obvious example of suboptimality would be
'bar': { 'tvpe': 'int' }
The previous patch's
if isinstance(value, dict) and 'type' in value:
check_type(info, source, value['type'], allow_array,
allow_dict, allow_optional, allow_metas)
if 'if' in value:
check_if(value, info)
check_unknown_keys(info, value, {'type', 'if'})
return
else:
raise QAPISemError(info, "%s should be a type name" % source)
should be improved to something like
if not isinstance(value, dict):
raise QAPISemError(
info, "%s should be a type name or dictionary" % source)
if 'type' not in value:
raise QAPISemError(
info, "%s must have a member 'type'" % source)
check_type(info, source, value['type'], allow_array,
allow_dict, allow_optional, allow_metas)
if 'if' in value:
check_if(value, info)
check_unknown_keys(info, value, {'type', 'if'})
return
producing
struct-if-invalid.json:2: Member 'bar' of 'data' for struct 'TestIfStruct' must have a member 'type'
The fact that I missed this in review of the code, but noticed it in the
tests is why I want tests added together with the code they test.
Nitpick: the file name struct-if-invalid makes me expect an invalid if.
Not the case. It's a missing type. Let's rename accordingly.
> diff --git a/tests/qapi-schema/struct-if-invalid.out b/tests/qapi-schema/struct-if-invalid.out
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/tests/qapi-schema/struct-member-type.err b/tests/qapi-schema/struct-member-type.err
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/tests/qapi-schema/struct-member-type.exit b/tests/qapi-schema/struct-member-type.exit
> new file mode 100644
> index 0000000000..573541ac97
> --- /dev/null
> +++ b/tests/qapi-schema/struct-member-type.exit
> @@ -0,0 +1 @@
> +0
> diff --git a/tests/qapi-schema/struct-member-type.json b/tests/qapi-schema/struct-member-type.json
> new file mode 100644
> index 0000000000..8b33027817
> --- /dev/null
> +++ b/tests/qapi-schema/struct-member-type.json
> @@ -0,0 +1,2 @@
> +# check member 'a' with 'type' key only
> +{ 'struct': 'foo', 'data': { 'a': { 'type': 'str' } } }
> diff --git a/tests/qapi-schema/struct-member-type.out b/tests/qapi-schema/struct-member-type.out
> new file mode 100644
> index 0000000000..04b969d2e3
> --- /dev/null
> +++ b/tests/qapi-schema/struct-member-type.out
> @@ -0,0 +1,12 @@
> +enum QType
> + prefix QTYPE
> + member none:
> + member qnull:
> + member qnum:
> + member qstring:
> + member qdict:
> + member qlist:
> + member qbool:
> +object foo
> + member a: str optional=False
> +object q_empty
This is a positive test, isn't it? Positive tests go into
qapi-schema-test.json.
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 26/50] qapi: add 'if' on union variants
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 26/50] qapi: add 'if' on union variants Marc-André Lureau
@ 2017-12-11 10:36 ` Markus Armbruster
2018-01-11 21:32 ` Marc-André Lureau
0 siblings, 1 reply; 118+ messages in thread
From: Markus Armbruster @ 2017-12-11 10:36 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Michael Roth
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi.py | 15 ++++++++++-----
> tests/qapi-schema/qapi-schema-test.json | 7 ++++++-
> tests/qapi-schema/qapi-schema-test.out | 8 ++++++++
> tests/qapi-schema/test-qapi.py | 5 ++++-
> 4 files changed, 28 insertions(+), 7 deletions(-)
>
> diff --git a/scripts/qapi.py b/scripts/qapi.py
> index 15711f96fa..2f14edfa1f 100644
> --- a/scripts/qapi.py
> +++ b/scripts/qapi.py
> @@ -1412,8 +1412,8 @@ class QAPISchemaObjectTypeVariants(object):
> class QAPISchemaObjectTypeVariant(QAPISchemaObjectTypeMember):
> role = 'branch'
>
> - def __init__(self, name, typ):
> - QAPISchemaObjectTypeMember.__init__(self, name, typ, False)
> + def __init__(self, name, typ, ifcond=None):
> + QAPISchemaObjectTypeMember.__init__(self, name, typ, False, ifcond)
>
>
> class QAPISchemaAlternateType(QAPISchemaType):
> @@ -1674,13 +1674,18 @@ class QAPISchema(object):
> return QAPISchemaObjectTypeVariant(case, typ)
>
> def _make_simple_variant(self, case, typ, info):
> + ifcond = None
> + if isinstance(typ, dict):
> + check_unknown_keys(info, typ, {'type', 'if'})
> + ifcond = typ.get('if')
> + typ = typ['type']
> if isinstance(typ, list):
> assert len(typ) == 1
> typ = self._make_array_type(typ[0], info)
> typ = self._make_implicit_object_type(
> typ, info, None, self.lookup_type(typ).ifcond,
> 'wrapper', [self._make_member('data', typ, info)])
> - return QAPISchemaObjectTypeVariant(case, typ)
> + return QAPISchemaObjectTypeVariant(case, typ, ifcond)
>
> def _def_union_type(self, expr, info, doc):
> name = expr['union']
> @@ -1700,8 +1705,8 @@ class QAPISchema(object):
> else:
> variants = [self._make_simple_variant(key, value, info)
> for (key, value) in data.iteritems()]
> - typ = self._make_implicit_enum_type(name, info, ifcond,
> - [v.name for v in variants])
> + values = [{'name': v.name, 'if': v.ifcond} for v in variants]
> + typ = self._make_implicit_enum_type(name, info, ifcond, values)
> tag_member = QAPISchemaObjectTypeMember('type', typ, False)
> members = [tag_member]
> self._def_entity(
> diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
> index 5cfccabb3d..895e80a978 100644
> --- a/tests/qapi-schema/qapi-schema-test.json
> +++ b/tests/qapi-schema/qapi-schema-test.json
> @@ -200,9 +200,14 @@
> [ 'foo', { 'name' : 'bar', 'if': 'defined(TEST_IF_ENUM_BAR)' } ],
> 'if': 'defined(TEST_IF_ENUM)' }
>
> -{ 'union': 'TestIfUnion', 'data': { 'foo': 'TestStruct' },
> +{ 'union': 'TestIfUnion', 'data':
> + { 'foo': 'TestStruct',
> + 'union_bar': { 'type': 'str', 'if': 'defined(TEST_IF_UNION_BAR)'} },
> 'if': 'defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)' }
>
> +{ 'command': 'TestIfUnionCmd', 'data': { 'union_cmd_arg': 'TestIfUnion' },
> + 'if': 'defined(TEST_IF_UNION)' }
> +
> { 'alternate': 'TestIfAlternate', 'data': { 'foo': 'int', 'bar': 'TestStruct' },
> 'if': 'defined(TEST_IF_ALT) && defined(TEST_IF_STRUCT)' }
>
> diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
> index 6df4e49c69..ee009c5626 100644
> --- a/tests/qapi-schema/qapi-schema-test.out
> +++ b/tests/qapi-schema/qapi-schema-test.out
> @@ -87,9 +87,14 @@ object TestIfUnion
> member type: TestIfUnionKind optional=False
> tag type
> case foo: q_obj_TestStruct-wrapper
> + case union_bar: q_obj_str-wrapper if=defined(TEST_IF_UNION_BAR)
PATCH 22, but I only spotted it here. We say "if=COND" in some places,
...
> if defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)
> +command TestIfUnionCmd q_obj_TestIfUnionCmd-arg -> None
> + gen=True success_response=True boxed=False
> + if defined(TEST_IF_UNION)
... and "if COND" in other places. I guess the '=' is there to match
existing flag printing like optional=BOOL.
I'd prefer less decorated output, i.e. instead of
enum TestIfEnum
member foo:
member bar: if=defined(TEST_IF_ENUM_BAR)
if defined(TEST_IF_ENUM)
something like
enum TestIfEnum
member foo
member bar
if defined(TEST_IF_ENUM_BAR)
if defined(TEST_IF_ENUM)
Could touch that up on commit.
> enum TestIfUnionKind
> member foo:
> + member union_bar: if=defined(TEST_IF_UNION_BAR)
> if defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)
> object TestStruct
> member integer: int optional=False
> @@ -235,6 +240,9 @@ object q_obj_TestIfEvent-arg
> member foo: TestIfStruct optional=False
> member bar: TestIfEnum optional=False if=defined(TEST_IF_EVT_BAR)
> if defined(TEST_IF_EVT) && defined(TEST_IF_STRUCT)
> +object q_obj_TestIfUnionCmd-arg
> + member union_cmd_arg: TestIfUnion optional=False
> + if defined(TEST_IF_UNION)
> object q_obj_TestStruct-wrapper
> member data: TestStruct optional=False
> object q_obj_UserDefFlatUnion2-base
> diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
> index a86c3b5ee1..87a8efff78 100644
> --- a/tests/qapi-schema/test-qapi.py
> +++ b/tests/qapi-schema/test-qapi.py
> @@ -65,7 +65,10 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
> if variants:
> print ' tag %s' % variants.tag_member.name
> for v in variants.variants:
> - print ' case %s: %s' % (v.name, v.type.name)
> + print ' case %s: %s' % (v.name, v.type.name),
> + if v.ifcond:
> + print 'if=%s' % v.ifcond,
> + print
>
> @staticmethod
> def _print_if(ifcond):
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 28/50] qapi: add 'if' to alternate variant
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 28/50] qapi: add 'if' to alternate variant Marc-André Lureau
@ 2017-12-12 14:51 ` Markus Armbruster
0 siblings, 0 replies; 118+ messages in thread
From: Markus Armbruster @ 2017-12-12 14:51 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Michael Roth
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi.py | 9 ++++++++-
> tests/qapi-schema/qapi-schema-test.json | 6 +++++-
> tests/qapi-schema/qapi-schema-test.out | 8 +++++++-
> 3 files changed, 20 insertions(+), 3 deletions(-)
>
> diff --git a/scripts/qapi.py b/scripts/qapi.py
> index 2f14edfa1f..19e48bd4d2 100644
> --- a/scripts/qapi.py
> +++ b/scripts/qapi.py
> @@ -849,6 +849,9 @@ def check_alternate(expr, info):
for (key, value) in members.items():
check_name(info, "Member of alternate '%s'" % name, key)
# Ensure alternates have no type conflicts.
> check_type(info, "Member '%s' of alternate '%s'" % (key, name),
> value,
> allow_metas=['built-in', 'union', 'struct', 'enum'])
> + if isinstance(value, dict):
> + check_unknown_keys(info, value, {'type', 'if'})
> + value = value['type']
> qtype = find_alternate_member_qtype(value)
> if not qtype:
> raise QAPISemError(info, "Alternate '%s' member '%s' cannot use "
I stared at this some because I couldn't see the check_if(). Looks like
it's done in check_type(). I guess I'm hitting the limits of what I can
do in *patch* review, and to do better, I'd have to go through the
resulting code with a fine comb.
You generalize the right hand side from "TYPE" to {"type": "TYPE", "if:
"IFCOND"}, where "if" is optional. The old "TYPE" becomes syntactic
sugar for {"type": "TYPE"}. Two remarks:
* Since the right hand side is more than just a type, the name
check_type() is now inappropriate. Since PATCH 23.
* The sane way to do syntactic sugar is to desugar at the first
opportunity. You do the opposite: you handle the new aspect of the
general form first, and then rewrite it to the sugared form for
further processing, most probably to reduce churn. Reducing churn is
good, but I find the resulting code hard to follow, because @value
changes meaning halfway through. May well apply to the other similar
patches, too.
> @@ -1671,7 +1674,11 @@ class QAPISchema(object):
> None))
>
> def _make_variant(self, case, typ):
> - return QAPISchemaObjectTypeVariant(case, typ)
> + ifcond = None
> + if isinstance(typ, dict):
> + ifcond = typ.get('if')
> + typ = typ['type']
> + return QAPISchemaObjectTypeVariant(case, typ, ifcond)
>
> def _make_simple_variant(self, case, typ, info):
> ifcond = None
> diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
> index 895e80a978..f7a62b24d1 100644
> --- a/tests/qapi-schema/qapi-schema-test.json
> +++ b/tests/qapi-schema/qapi-schema-test.json
> @@ -208,9 +208,13 @@
> { 'command': 'TestIfUnionCmd', 'data': { 'union_cmd_arg': 'TestIfUnion' },
> 'if': 'defined(TEST_IF_UNION)' }
>
> -{ 'alternate': 'TestIfAlternate', 'data': { 'foo': 'int', 'bar': 'TestStruct' },
> +{ 'alternate': 'TestIfAlternate', 'data':
> + { 'foo': 'int', 'alt_bar': { 'type': 'TestStruct', 'if': 'defined(TEST_IF_ALT_BAR)'} },
> 'if': 'defined(TEST_IF_ALT) && defined(TEST_IF_STRUCT)' }
>
> +{ 'command': 'TestIfAlternateCmd', 'data': { 'alt_cmd_arg': 'TestIfAlternate' },
> + 'if': 'defined(TEST_IF_ALT)' }
> +
> { 'command': 'TestIfCmd', 'data':
> { 'foo': 'TestIfStruct',
> 'bar': { 'type': 'TestIfEnum', 'if': 'defined(TEST_IF_CMD_BAR)' } },
> diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
> index ee009c5626..6887e49c9b 100644
> --- a/tests/qapi-schema/qapi-schema-test.out
> +++ b/tests/qapi-schema/qapi-schema-test.out
> @@ -67,8 +67,11 @@ enum QType
> alternate TestIfAlternate
> tag type
> case foo: int
> - case bar: TestStruct
> + case alt_bar: TestStruct if=defined(TEST_IF_ALT_BAR)
> if defined(TEST_IF_ALT) && defined(TEST_IF_STRUCT)
> +command TestIfAlternateCmd q_obj_TestIfAlternateCmd-arg -> None
> + gen=True success_response=True boxed=False
> + if defined(TEST_IF_ALT)
> command TestIfCmd q_obj_TestIfCmd-arg -> None
> gen=True success_response=True boxed=False
> if defined(TEST_IF_CMD) && defined(TEST_IF_STRUCT)
> @@ -232,6 +235,9 @@ object q_obj_EVENT_D-arg
> member b: str optional=False
> member c: str optional=True
> member enum3: EnumOne optional=True
> +object q_obj_TestIfAlternateCmd-arg
> + member alt_cmd_arg: TestIfAlternate optional=False
> + if defined(TEST_IF_ALT)
> object q_obj_TestIfCmd-arg
> member foo: TestIfStruct optional=False
> member bar: TestIfEnum optional=False if=defined(TEST_IF_CMD_BAR)
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 30/50] qapi: add #if conditions to generated alternate variants
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 30/50] qapi: add #if conditions to generated alternate variants Marc-André Lureau
@ 2017-12-12 19:25 ` Markus Armbruster
0 siblings, 0 replies; 118+ messages in thread
From: Markus Armbruster @ 2017-12-12 19:25 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Michael Roth
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Mostly covered by previous patches already.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi-introspect.py | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
> index ef2d5577db..d6194ff702 100644
> --- a/scripts/qapi-introspect.py
> +++ b/scripts/qapi-introspect.py
> @@ -172,7 +172,7 @@ const QLitObject %(c_name)s = %(c_string)s;
>
> def visit_alternate_type(self, name, info, ifcond, variants):
> self._gen_qlit(name, 'alternate',
> - {'members': [{'type': self._use_type(m.type)}
> + {'members': [({'type': self._use_type(m.type)}, m.ifcond)
> for m in variants.variants]}, ifcond)
>
> def visit_command(self, name, info, ifcond, arg_type, ret_type,
Adds blank lines to qmp-introspect.c, just like PATCH 12, which see.
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 31/50] docs: document schema configuration
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 31/50] docs: document schema configuration Marc-André Lureau
@ 2017-12-13 10:41 ` Markus Armbruster
2017-12-13 19:49 ` Eric Blake
0 siblings, 1 reply; 118+ messages in thread
From: Markus Armbruster @ 2017-12-13 10:41 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Eric Blake
Cc: Eric for an additional pair of eyeballs.
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> docs/devel/qapi-code-gen.txt | 37 +++++++++++++++++++++++++++++++++++++
> 1 file changed, 37 insertions(+)
>
> diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt
> index 0a90f2278a..24fc6f74ee 100644
> --- a/docs/devel/qapi-code-gen.txt
> +++ b/docs/devel/qapi-code-gen.txt
> @@ -682,6 +682,43 @@ Example: Red Hat, Inc. controls redhat.com, and may therefore add a
> downstream command __com.redhat_drive-mirror.
>
>
> +=== Configuring the schema ===
> +
> +'struct', 'enum', 'union', 'alternate', 'command' and 'event'
> +top-level QAPI expressions can take a 'if' keyword like:
an 'if' key
> +
> +{ 'struct': 'IfStruct', 'data': { 'foo': 'int' },
> + 'if': 'defined(IF_STRUCT) && defined(FOO)' }
Perhaps we should add something like
Code generated for such conditional definitions will be guarded with
#if IFCOND, where IFCOND is the value of the 'if' key.
> +
> +Members can be exploded as dictionnary with 'type' & 'if' keys:
dictionary
I get what you mean by "can be exploded", but can we phrase this more
clearly?
In section "Struct types", we have
A struct is a dictionary containing a single 'data' key whose value is
a dictionary; the dictionary may be empty. This corresponds to a
struct in C or an Object in JSON. Each value of the 'data' dictionary
must be the name of a type, or a one-element array containing a type
name.
The part "must be the name of a type, or a one-element array containing
a type" name is now wrong.
Likewise, in section "Enumeration types"
An enumeration type is a dictionary containing a single 'data' key
whose value is a list of strings.
> +
> +{ 'struct': 'IfStruct', 'data':
> + { 'foo': 'int',
> + 'bar': { 'type': 'int', 'if': 'defined(IF_STRUCT_BAR)'} } }
Perhaps add something like
Code generated for such conditional members will be guarded with #if
IFCOND, where IFCOND is the value of the 'if' key.
> +
> +Enum values can be exploded as dictionnary with 'name' & 'if' keys:
dictionnary and exploded again.
> +
> +{ 'enum': 'IfEnum', 'data':
> + [ 'foo',
> + { 'name' : 'bar', 'if': 'defined(IF_ENUM_BAR)' } ] }
> +
> +The C code generators will wrap the corresponding lines with #if / #endif
> +pre-processor conditions for a given 'if' value.
> +
> +Example for enum values:
> +
> +enum IfEnum {
> + IF_ENUM_FOO,
> +#if defined(IF_ENUM_BAR)
> + IF_ENUM_BAR,
> +#endif /* defined(IF_ENUM_BAR) */
> + IF_ENUM__MAX
> +}
Hmm. If enumeration documentation profits from an example, it stands to
reason that the previous two would, too.
Should we (additionally?) add examples of 'if' in section "Code
generation"?
> +
> +Please note that you are responsbile to ensure that the C code will
> +compile with an arbitrary combination of conditions, since the
> +generators are unable to check it at this point.
> +
> == Client JSON Protocol introspection ==
>
> Clients of a Client JSON Protocol commonly need to figure out what
Do we need to update section "Client JSON Protocol introspection"?
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 32/50] qapi2texi: add 'If:' section to generated documentation
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 32/50] qapi2texi: add 'If:' section to generated documentation Marc-André Lureau
@ 2017-12-13 12:35 ` Markus Armbruster
2017-12-13 19:54 ` Eric Blake
0 siblings, 1 reply; 118+ messages in thread
From: Markus Armbruster @ 2017-12-13 12:35 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Michael Roth, Eric Blake
Cc: Eric for an additional pair of eyeballs.
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> The documentation is generated only once, and doesn't know C
> pre-conditions. Add 'If:' sections for top-level entities.
Is this what we want?
QMP also exists only once. Should the generated qemu-qmp-ref.* document
that instance of QMP, or should it document all potential instances of
QMP?
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi2texi.py | 24 +++++++++++++-----------
> 1 file changed, 13 insertions(+), 11 deletions(-)
>
> diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py
> index e72e7cfe0b..150e7045d2 100755
> --- a/scripts/qapi2texi.py
> +++ b/scripts/qapi2texi.py
> @@ -132,7 +132,6 @@ def texi_enum_value(value):
> """Format a table of members item for an enumeration value"""
> return '@item @code{%s}\n' % value.name
>
> -
> def texi_member(member, suffix=''):
> """Format a table of members item for an object type member"""
> typ = member.type.doc_type()
Spurious whitespace change. PEP8 wants the original spacing here.
> @@ -175,7 +174,7 @@ def texi_members(doc, what, base, variants, member_func):
> return '\n@b{%s:}\n@table @asis\n%s@end table\n' % (what, items)
>
>
> -def texi_sections(doc):
> +def texi_sections(doc, ifcond):
> """Format additional sections following arguments"""
> body = ''
> for section in doc.sections:
> @@ -189,14 +188,16 @@ def texi_sections(doc):
> body += '\n\n@b{%s:}\n' % name
>
> body += func(doc)
> + if ifcond:
> + body += '\n\n@b{If:} @code{%s}' % ifcond
> return body
>
>
> -def texi_entity(doc, what, base=None, variants=None,
> +def texi_entity(doc, what, ifcond, base=None, variants=None,
> member_func=texi_member):
> return (texi_body(doc)
> + texi_members(doc, what, base, variants, member_func)
> - + texi_sections(doc))
> + + texi_sections(doc, ifcond))
>
>
> class QAPISchemaGenDocVisitor(qapi.QAPISchemaVisitor):
> @@ -213,7 +214,7 @@ class QAPISchemaGenDocVisitor(qapi.QAPISchemaVisitor):
> self.out += '\n'
> self.out += TYPE_FMT(type='Enum',
> name=doc.symbol,
> - body=texi_entity(doc, 'Values',
> + body=texi_entity(doc, 'Values', ifcond,
> member_func=texi_enum_value))
>
> def visit_object_type(self, name, info, ifcond, base, members, variants):
> @@ -224,7 +225,8 @@ class QAPISchemaGenDocVisitor(qapi.QAPISchemaVisitor):
> self.out += '\n'
> self.out += TYPE_FMT(type='Object',
> name=doc.symbol,
> - body=texi_entity(doc, 'Members', base, variants))
> + body=texi_entity(doc, 'Members', ifcond,
> + base, variants))
>
> def visit_alternate_type(self, name, info, ifcond, variants):
> doc = self.cur_doc
> @@ -232,7 +234,7 @@ class QAPISchemaGenDocVisitor(qapi.QAPISchemaVisitor):
> self.out += '\n'
> self.out += TYPE_FMT(type='Alternate',
> name=doc.symbol,
> - body=texi_entity(doc, 'Members'))
> + body=texi_entity(doc, 'Members', ifcond))
>
> def visit_command(self, name, info, ifcond, arg_type, ret_type,
> gen, success_response, boxed):
> @@ -242,9 +244,9 @@ class QAPISchemaGenDocVisitor(qapi.QAPISchemaVisitor):
> if boxed:
> body = texi_body(doc)
> body += '\n@b{Arguments:} the members of @code{%s}' % arg_type.name
> - body += texi_sections(doc)
> + body += texi_sections(doc, ifcond)
> else:
> - body = texi_entity(doc, 'Arguments')
> + body = texi_entity(doc, 'Arguments', ifcond)
> self.out += MSG_FMT(type='Command',
> name=doc.symbol,
> body=body)
> @@ -255,7 +257,7 @@ class QAPISchemaGenDocVisitor(qapi.QAPISchemaVisitor):
> self.out += '\n'
> self.out += MSG_FMT(type='Event',
> name=doc.symbol,
> - body=texi_entity(doc, 'Arguments'))
> + body=texi_entity(doc, 'Arguments', ifcond))
>
> def symbol(self, doc, entity):
> self.cur_doc = doc
> @@ -266,7 +268,7 @@ class QAPISchemaGenDocVisitor(qapi.QAPISchemaVisitor):
> assert not doc.args
> if self.out:
> self.out += '\n'
> - self.out += texi_body(doc) + texi_sections(doc)
> + self.out += texi_body(doc) + texi_sections(doc, None)
>
>
> def texi_schema(schema):
Missing: coverage in tests/qapi-schema/doc-good.json.
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 27/50] qapi: add #if conditions to generated variants
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 27/50] qapi: add #if conditions to generated variants Marc-André Lureau
@ 2017-12-13 12:37 ` Markus Armbruster
0 siblings, 0 replies; 118+ messages in thread
From: Markus Armbruster @ 2017-12-13 12:37 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Michael Roth
Adds blank lines to qmp-introspect.c, just like PATCH 12, which see.
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 36/50] qapi: add conditions to VNC type/commands/events on the schema
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 36/50] qapi: add conditions to VNC type/commands/events on the schema Marc-André Lureau
@ 2017-12-13 14:12 ` Markus Armbruster
2017-12-13 14:20 ` Daniel P. Berrange
0 siblings, 1 reply; 118+ messages in thread
From: Markus Armbruster @ 2017-12-13 14:12 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Dr. David Alan Gilbert, Gerd Hoffmann, Daniel P. Berrange
Cc: Daniel for his opinion on QCryptoCipherAlgorithm member des-rfb.
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Add #if defined(CONFIG_VNC) in generated code, and adjust the
> qmp/hmp code accordingly.
>
> Commands made conditional:
>
> * query-vnc, query-vnc-servers, change-vnc-password
>
> Before the patch, the commands for !CONFIG_VNC are stubs that fail
> like this:
>
> {"error": {"class": "GenericError",
> "desc": "The feature 'vnc' is not enabled"}}
>
> Afterwards, they fail like this:
>
> {"error": {"class": "CommandNotFound",
> "desc": "The command FOO has not been found"}}
>
> I call that an improvement, because it lets clients distinguish
> between command unavailable (class CommandNotFound) and command failed
> (class GenericError).
Moreover, query-qmp-schema no longer reports the command as available.
That's the point of this series! Let's spell it out in the commit
message.
Same for events etc.
How this affects HMP is worth describing, too.
> Events made conditional:
>
> * VNC_CONNECTED, VNC_INITIALIZED, VNC_DISCONNECTED
>
> Enum made conditional:
The enum isn't made conditional, only one of its values is. Suggest "
Enumeration values made conditional:".
> * QCryptoCipherAlgorithm
>
> # @des-rfb: RFB specific variant of single DES. Do not use except in VNC.
Daniel, is this okay?
> Occurrences of VNC (case insensitive) in the schema that aren't
> covered by this change:
>
> * add_client
>
> Command has other uses, including "socket bases character devices".
> These are unconditional as far as I can tell.
>
> * set_password, expire_password
>
> In theory, these commands could be used for managing any service's
> password. In practice, they're used for VNC and SPICE services.
> They're documented for "remote display session" / "remote display
> server".
>
> The service is selected by argument @protocol. The code special-cases
> protocol-specific argument checking, then calls a protocol-specific
> function to do the work. If it fails, the command fails with "Could
> not set password". It does when the service isn't compiled in (it's a
> stub then).
>
> We could make these commands conditional on the conjunction of all
> services [currently: defined(CONFIG_VNC) || defined(CONFIG_SPICE)],
> but I doubt it's worthwhile.
What could be worthwhile: change @protocol from 'str' to suitable
enumeration type with appropriately conditional values, so that
introspection correctly reports available functioniality.
Not possible for add_client, because that one overloads protocol
further: "spice" and "vnc" are special, anything else is interpreted as
character device name. Character devices named "spice" or "vnc" don't
work. Bad design. Needs to be replaced & deprecated.
> * change
>
> Command has other uses, namely changing media.
> This patch inlines a stub; no functional change.
Already deprecated.
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> qapi/crypto.json | 3 ++-
> qapi/ui.json | 45 ++++++++++++++++++++++++++++-----------------
> ui/vnc.h | 2 ++
> crypto/cipher-builtin.c | 9 +++++++++
> crypto/cipher-gcrypt.c | 10 ++++++++--
> crypto/cipher-nettle.c | 14 +++++++++++---
> crypto/cipher.c | 13 +++++++++++--
> hmp.c | 9 ++++++++-
> qmp.c | 30 ++++--------------------------
> tests/test-crypto-cipher.c | 2 ++
> hmp-commands-info.hx | 2 ++
> 11 files changed, 87 insertions(+), 52 deletions(-)
>
> diff --git a/qapi/crypto.json b/qapi/crypto.json
> index 288bc056ef..09535b7be2 100644
> --- a/qapi/crypto.json
> +++ b/qapi/crypto.json
> @@ -79,7 +79,8 @@
> { 'enum': 'QCryptoCipherAlgorithm',
> 'prefix': 'QCRYPTO_CIPHER_ALG',
> 'data': ['aes-128', 'aes-192', 'aes-256',
> - 'des-rfb', '3des',
> + { 'name': 'des-rfb', 'if': 'defined(CONFIG_VNC)' },
> + '3des',
> 'cast5-128',
> 'serpent-128', 'serpent-192', 'serpent-256',
> 'twofish-128', 'twofish-192', 'twofish-256']}
> diff --git a/qapi/ui.json b/qapi/ui.json
> index e5d6610b4a..4b573d214b 100644
> --- a/qapi/ui.json
> +++ b/qapi/ui.json
> @@ -369,7 +369,8 @@
> 'data': { 'host': 'str',
> 'service': 'str',
> 'family': 'NetworkAddressFamily',
> - 'websocket': 'bool' } }
> + 'websocket': 'bool' },
> + 'if': 'defined(CONFIG_VNC)' }
>
> ##
> # @VncServerInfo:
> @@ -383,7 +384,8 @@
> ##
> { 'struct': 'VncServerInfo',
> 'base': 'VncBasicInfo',
> - 'data': { '*auth': 'str' } }
> + 'data': { '*auth': 'str' },
> + 'if': 'defined(CONFIG_VNC)' }
>
> ##
> # @VncClientInfo:
> @@ -400,7 +402,8 @@
> ##
> { 'struct': 'VncClientInfo',
> 'base': 'VncBasicInfo',
> - 'data': { '*x509_dname': 'str', '*sasl_username': 'str' } }
> + 'data': { '*x509_dname': 'str', '*sasl_username': 'str' },
> + 'if': 'defined(CONFIG_VNC)' }
>
> ##
> # @VncInfo:
> @@ -441,7 +444,8 @@
> { 'struct': 'VncInfo',
> 'data': {'enabled': 'bool', '*host': 'str',
> '*family': 'NetworkAddressFamily',
> - '*service': 'str', '*auth': 'str', '*clients': ['VncClientInfo']} }
> + '*service': 'str', '*auth': 'str', '*clients': ['VncClientInfo']},
> + 'if': 'defined(CONFIG_VNC)' }
>
> ##
> # @VncPrimaryAuth:
> @@ -452,7 +456,8 @@
> ##
> { 'enum': 'VncPrimaryAuth',
> 'data': [ 'none', 'vnc', 'ra2', 'ra2ne', 'tight', 'ultra',
> - 'tls', 'vencrypt', 'sasl' ] }
> + 'tls', 'vencrypt', 'sasl' ],
> + 'if': 'defined(CONFIG_VNC)' }
>
> ##
> # @VncVencryptSubAuth:
> @@ -466,8 +471,8 @@
> 'tls-none', 'x509-none',
> 'tls-vnc', 'x509-vnc',
> 'tls-plain', 'x509-plain',
> - 'tls-sasl', 'x509-sasl' ] }
> -
> + 'tls-sasl', 'x509-sasl' ],
> + 'if': 'defined(CONFIG_VNC)' }
>
> ##
> # @VncServerInfo2:
> @@ -484,8 +489,8 @@
> { 'struct': 'VncServerInfo2',
> 'base': 'VncBasicInfo',
> 'data': { 'auth' : 'VncPrimaryAuth',
> - '*vencrypt' : 'VncVencryptSubAuth' } }
> -
> + '*vencrypt' : 'VncVencryptSubAuth' },
> + 'if': 'defined(CONFIG_VNC)' }
>
> ##
> # @VncInfo2:
> @@ -517,7 +522,8 @@
> 'clients' : ['VncClientInfo'],
> 'auth' : 'VncPrimaryAuth',
> '*vencrypt' : 'VncVencryptSubAuth',
> - '*display' : 'str' } }
> + '*display' : 'str' },
> + 'if': 'defined(CONFIG_VNC)' }
>
> ##
> # @query-vnc:
> @@ -548,8 +554,8 @@
> # }
> #
> ##
> -{ 'command': 'query-vnc', 'returns': 'VncInfo' }
> -
> +{ 'command': 'query-vnc', 'returns': 'VncInfo',
> + 'if': 'defined(CONFIG_VNC)' }
> ##
> # @query-vnc-servers:
> #
> @@ -559,7 +565,8 @@
> #
> # Since: 2.3
> ##
> -{ 'command': 'query-vnc-servers', 'returns': ['VncInfo2'] }
> +{ 'command': 'query-vnc-servers', 'returns': ['VncInfo2'],
> + 'if': 'defined(CONFIG_VNC)' }
>
> ##
> # @change-vnc-password:
> @@ -573,7 +580,8 @@
> # Notes: An empty password in this command will set the password to the empty
> # string. Existing clients are unaffected by executing this command.
> ##
> -{ 'command': 'change-vnc-password', 'data': {'password': 'str'} }
> +{ 'command': 'change-vnc-password', 'data': {'password': 'str'},
> + 'if': 'defined(CONFIG_VNC)' }
>
> ##
> # @VNC_CONNECTED:
> @@ -602,7 +610,8 @@
> ##
> { 'event': 'VNC_CONNECTED',
> 'data': { 'server': 'VncServerInfo',
> - 'client': 'VncBasicInfo' } }
> + 'client': 'VncBasicInfo' },
> + 'if': 'defined(CONFIG_VNC)' }
>
> ##
> # @VNC_INITIALIZED:
> @@ -629,7 +638,8 @@
> ##
> { 'event': 'VNC_INITIALIZED',
> 'data': { 'server': 'VncServerInfo',
> - 'client': 'VncClientInfo' } }
> + 'client': 'VncClientInfo' },
> + 'if': 'defined(CONFIG_VNC)' }
>
> ##
> # @VNC_DISCONNECTED:
> @@ -655,7 +665,8 @@
> ##
> { 'event': 'VNC_DISCONNECTED',
> 'data': { 'server': 'VncServerInfo',
> - 'client': 'VncClientInfo' } }
> + 'client': 'VncClientInfo' },
> + 'if': 'defined(CONFIG_VNC)' }
>
> ##
> # = Input
> diff --git a/ui/vnc.h b/ui/vnc.h
> index 694cf32ca9..5572bfdc9e 100644
> --- a/ui/vnc.h
> +++ b/ui/vnc.h
> @@ -291,7 +291,9 @@ struct VncState
> bool encode_ws;
> bool websocket;
>
> +#ifdef CONFIG_VNC
> VncClientInfo *info;
> +#endif
>
> Buffer output;
> Buffer input;
> diff --git a/crypto/cipher-builtin.c b/crypto/cipher-builtin.c
> index d8c811fd33..647850843e 100644
> --- a/crypto/cipher-builtin.c
> +++ b/crypto/cipher-builtin.c
> @@ -35,17 +35,22 @@ struct QCryptoCipherBuiltinAES {
> QCryptoCipherBuiltinAESContext key_tweak;
> uint8_t iv[AES_BLOCK_SIZE];
> };
> +
> +#ifdef CONFIG_VNC
> typedef struct QCryptoCipherBuiltinDESRFB QCryptoCipherBuiltinDESRFB;
> struct QCryptoCipherBuiltinDESRFB {
> uint8_t *key;
> size_t nkey;
> };
> +#endif
>
> typedef struct QCryptoCipherBuiltin QCryptoCipherBuiltin;
> struct QCryptoCipherBuiltin {
> union {
> QCryptoCipherBuiltinAES aes;
> +#ifdef CONFIG_VNC
> QCryptoCipherBuiltinDESRFB desrfb;
> +#endif
> } state;
> size_t blocksize;
> void (*free)(QCryptoCipher *cipher);
> @@ -403,7 +408,9 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
> QCryptoCipherMode mode)
> {
> switch (alg) {
> +#ifdef CONFIG_VNC
> case QCRYPTO_CIPHER_ALG_DES_RFB:
> +#endif
> case QCRYPTO_CIPHER_ALG_AES_128:
> case QCRYPTO_CIPHER_ALG_AES_192:
> case QCRYPTO_CIPHER_ALG_AES_256:
> @@ -449,9 +456,11 @@ static QCryptoCipherBuiltin *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
> }
>
> switch (alg) {
> +#ifdef CONFIG_VNC
> case QCRYPTO_CIPHER_ALG_DES_RFB:
> ctxt = qcrypto_cipher_init_des_rfb(mode, key, nkey, errp);
> break;
> +#endif
> case QCRYPTO_CIPHER_ALG_AES_128:
> case QCRYPTO_CIPHER_ALG_AES_192:
> case QCRYPTO_CIPHER_ALG_AES_256:
> diff --git a/crypto/cipher-gcrypt.c b/crypto/cipher-gcrypt.c
> index 10d75da75d..c240aaee26 100644
> --- a/crypto/cipher-gcrypt.c
> +++ b/crypto/cipher-gcrypt.c
> @@ -29,7 +29,9 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
> QCryptoCipherMode mode)
> {
> switch (alg) {
> +#ifdef CONFIG_VNC
> case QCRYPTO_CIPHER_ALG_DES_RFB:
> +#endif
> case QCRYPTO_CIPHER_ALG_3DES:
> case QCRYPTO_CIPHER_ALG_AES_128:
> case QCRYPTO_CIPHER_ALG_AES_192:
> @@ -114,10 +116,11 @@ static QCryptoCipherGcrypt *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
> }
>
> switch (alg) {
> +#ifdef CONFIG_VNC
> case QCRYPTO_CIPHER_ALG_DES_RFB:
> gcryalg = GCRY_CIPHER_DES;
> break;
> -
> +#endif
> case QCRYPTO_CIPHER_ALG_3DES:
> gcryalg = GCRY_CIPHER_3DES;
> break;
> @@ -181,6 +184,7 @@ static QCryptoCipherGcrypt *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
> }
> }
>
> +#ifdef CONFIG_VNC
> if (alg == QCRYPTO_CIPHER_ALG_DES_RFB) {
> /* We're using standard DES cipher from gcrypt, so we need
> * to munge the key so that the results are the same as the
> @@ -190,7 +194,9 @@ static QCryptoCipherGcrypt *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
> err = gcry_cipher_setkey(ctx->handle, rfbkey, nkey);
> g_free(rfbkey);
> ctx->blocksize = 8;
> - } else {
> + } else
> +#endif /* CONFIG_VNC */
> + {
> if (mode == QCRYPTO_CIPHER_MODE_XTS) {
> nkey /= 2;
> err = gcry_cipher_setkey(ctx->handle, key, nkey);
> diff --git a/crypto/cipher-nettle.c b/crypto/cipher-nettle.c
> index 3848cb3b3a..ace5ec20f6 100644
> --- a/crypto/cipher-nettle.c
> +++ b/crypto/cipher-nettle.c
> @@ -67,6 +67,7 @@ static void aes_decrypt_native(cipher_ctx_t ctx, cipher_length_t length,
> aes_decrypt(&aesctx->dec, length, dst, src);
> }
>
> +#ifdef CONFIG_VNC
> static void des_encrypt_native(cipher_ctx_t ctx, cipher_length_t length,
> uint8_t *dst, const uint8_t *src)
> {
> @@ -78,6 +79,7 @@ static void des_decrypt_native(cipher_ctx_t ctx, cipher_length_t length,
> {
> des_decrypt(ctx, length, dst, src);
> }
> +#endif
>
> static void des3_encrypt_native(cipher_ctx_t ctx, cipher_length_t length,
> uint8_t *dst, const uint8_t *src)
> @@ -141,6 +143,7 @@ static void aes_decrypt_wrapper(const void *ctx, size_t length,
> aes_decrypt(&aesctx->dec, length, dst, src);
> }
>
> +#ifdef CONFIG_VNC
> static void des_encrypt_wrapper(const void *ctx, size_t length,
> uint8_t *dst, const uint8_t *src)
> {
> @@ -152,6 +155,7 @@ static void des_decrypt_wrapper(const void *ctx, size_t length,
> {
> des_decrypt(ctx, length, dst, src);
> }
> +#endif
>
> static void des3_encrypt_wrapper(const void *ctx, size_t length,
> uint8_t *dst, const uint8_t *src)
> @@ -221,7 +225,9 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
> QCryptoCipherMode mode)
> {
> switch (alg) {
> +#ifdef CONFIG_VNC
> case QCRYPTO_CIPHER_ALG_DES_RFB:
> +#endif
> case QCRYPTO_CIPHER_ALG_3DES:
> case QCRYPTO_CIPHER_ALG_AES_128:
> case QCRYPTO_CIPHER_ALG_AES_192:
> @@ -271,7 +277,6 @@ static QCryptoCipherNettle *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
> Error **errp)
> {
> QCryptoCipherNettle *ctx;
> - uint8_t *rfbkey;
>
> switch (mode) {
> case QCRYPTO_CIPHER_MODE_ECB:
> @@ -292,7 +297,9 @@ static QCryptoCipherNettle *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
> ctx = g_new0(QCryptoCipherNettle, 1);
>
> switch (alg) {
> - case QCRYPTO_CIPHER_ALG_DES_RFB:
> +#ifdef CONFIG_VNC
> + case QCRYPTO_CIPHER_ALG_DES_RFB: {
> + uint8_t *rfbkey;
> ctx->ctx = g_new0(struct des_ctx, 1);
> rfbkey = qcrypto_cipher_munge_des_rfb_key(key, nkey);
> des_set_key(ctx->ctx, rfbkey);
> @@ -305,7 +312,8 @@ static QCryptoCipherNettle *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
>
> ctx->blocksize = DES_BLOCK_SIZE;
> break;
> -
> + }
> +#endif
> case QCRYPTO_CIPHER_ALG_3DES:
> ctx->ctx = g_new0(struct des3_ctx, 1);
> des3_set_key(ctx->ctx, key);
> diff --git a/crypto/cipher.c b/crypto/cipher.c
> index 0aad9d6d79..80355f4530 100644
> --- a/crypto/cipher.c
> +++ b/crypto/cipher.c
> @@ -28,7 +28,9 @@ static size_t alg_key_len[QCRYPTO_CIPHER_ALG__MAX] = {
> [QCRYPTO_CIPHER_ALG_AES_128] = 16,
> [QCRYPTO_CIPHER_ALG_AES_192] = 24,
> [QCRYPTO_CIPHER_ALG_AES_256] = 32,
> +#ifdef CONFIG_VNC
> [QCRYPTO_CIPHER_ALG_DES_RFB] = 8,
> +#endif
> [QCRYPTO_CIPHER_ALG_3DES] = 24,
> [QCRYPTO_CIPHER_ALG_CAST5_128] = 16,
> [QCRYPTO_CIPHER_ALG_SERPENT_128] = 16,
> @@ -43,7 +45,9 @@ static size_t alg_block_len[QCRYPTO_CIPHER_ALG__MAX] = {
> [QCRYPTO_CIPHER_ALG_AES_128] = 16,
> [QCRYPTO_CIPHER_ALG_AES_192] = 16,
> [QCRYPTO_CIPHER_ALG_AES_256] = 16,
> +#ifdef CONFIG_VNC
> [QCRYPTO_CIPHER_ALG_DES_RFB] = 8,
> +#endif
> [QCRYPTO_CIPHER_ALG_3DES] = 8,
> [QCRYPTO_CIPHER_ALG_CAST5_128] = 8,
> [QCRYPTO_CIPHER_ALG_SERPENT_128] = 16,
> @@ -106,8 +110,11 @@ qcrypto_cipher_validate_key_length(QCryptoCipherAlgorithm alg,
> }
>
> if (mode == QCRYPTO_CIPHER_MODE_XTS) {
> - if (alg == QCRYPTO_CIPHER_ALG_DES_RFB
> - || alg == QCRYPTO_CIPHER_ALG_3DES) {
> + if (
> +#ifdef CONFIG_VNC
> + alg == QCRYPTO_CIPHER_ALG_DES_RFB ||
> +#endif
> + alg == QCRYPTO_CIPHER_ALG_3DES) {
> error_setg(errp, "XTS mode not compatible with DES-RFB/3DES");
> return false;
> }
> @@ -131,6 +138,7 @@ qcrypto_cipher_validate_key_length(QCryptoCipherAlgorithm alg,
> return true;
> }
>
> +#if defined(CONFIG_VNC)
> #if defined(CONFIG_GCRYPT) || defined(CONFIG_NETTLE)
> static uint8_t *
> qcrypto_cipher_munge_des_rfb_key(const uint8_t *key,
> @@ -148,6 +156,7 @@ qcrypto_cipher_munge_des_rfb_key(const uint8_t *key,
> return ret;
> }
> #endif /* CONFIG_GCRYPT || CONFIG_NETTLE */
> +#endif /* CONFIG_VNC */
>
> #ifdef CONFIG_GCRYPT
> #include "crypto/cipher-gcrypt.c"
> diff --git a/hmp.c b/hmp.c
> index cd046c6d71..5893e5bf16 100644
> --- a/hmp.c
> +++ b/hmp.c
> @@ -604,6 +604,7 @@ void hmp_info_blockstats(Monitor *mon, const QDict *qdict)
> qapi_free_BlockStatsList(stats_list);
> }
>
> +#ifdef CONFIG_VNC
> /* Helper for hmp_info_vnc_clients, _servers */
> static void hmp_info_VncBasicInfo(Monitor *mon, VncBasicInfo *info,
> const char *name)
> @@ -691,6 +692,7 @@ void hmp_info_vnc(Monitor *mon, const QDict *qdict)
> qapi_free_VncInfo2List(info2l);
>
> }
> +#endif
>
> #ifdef CONFIG_SPICE
> void hmp_info_spice(Monitor *mon, const QDict *qdict)
> @@ -1702,12 +1704,14 @@ void hmp_eject(Monitor *mon, const QDict *qdict)
> hmp_handle_error(mon, &err);
> }
>
> +#ifdef CONFIG_VNC
> static void hmp_change_read_arg(void *opaque, const char *password,
> void *readline_opaque)
> {
> qmp_change_vnc_password(password, NULL);
> monitor_read_command(opaque, 1);
> }
> +#endif
>
> void hmp_change(Monitor *mon, const QDict *qdict)
> {
> @@ -1718,6 +1722,7 @@ void hmp_change(Monitor *mon, const QDict *qdict)
> BlockdevChangeReadOnlyMode read_only_mode = 0;
> Error *err = NULL;
>
> +#ifdef CONFIG_VNC
> if (strcmp(device, "vnc") == 0) {
> if (read_only) {
> monitor_printf(mon,
> @@ -1732,7 +1737,9 @@ void hmp_change(Monitor *mon, const QDict *qdict)
> }
> }
> qmp_change("vnc", target, !!arg, arg, &err);
> - } else {
> + } else
> +#endif
> + {
> if (read_only) {
> read_only_mode =
> qapi_enum_parse(&BlockdevChangeReadOnlyMode_lookup,
> diff --git a/qmp.c b/qmp.c
> index b86201e349..2c90dacb56 100644
> --- a/qmp.c
> +++ b/qmp.c
> @@ -130,22 +130,6 @@ void qmp_cpu_add(int64_t id, Error **errp)
> }
> }
>
> -#ifndef CONFIG_VNC
> -/* If VNC support is enabled, the "true" query-vnc command is
> - defined in the VNC subsystem */
> -VncInfo *qmp_query_vnc(Error **errp)
> -{
> - error_setg(errp, QERR_FEATURE_DISABLED, "vnc");
> - return NULL;
> -};
> -
> -VncInfo2List *qmp_query_vnc_servers(Error **errp)
> -{
> - error_setg(errp, QERR_FEATURE_DISABLED, "vnc");
> - return NULL;
> -};
> -#endif
> -
> #ifndef CONFIG_SPICE
> /*
> * qmp-commands.hx ensures that QMP command query-spice exists only
> @@ -403,23 +387,17 @@ static void qmp_change_vnc(const char *target, bool has_arg, const char *arg,
> qmp_change_vnc_listen(target, errp);
> }
> }
> -#else
> -void qmp_change_vnc_password(const char *password, Error **errp)
> -{
> - error_setg(errp, QERR_FEATURE_DISABLED, "vnc");
> -}
> -static void qmp_change_vnc(const char *target, bool has_arg, const char *arg,
> - Error **errp)
> -{
> - error_setg(errp, QERR_FEATURE_DISABLED, "vnc");
> -}
> #endif /* !CONFIG_VNC */
>
> void qmp_change(const char *device, const char *target,
> bool has_arg, const char *arg, Error **errp)
> {
> if (strcmp(device, "vnc") == 0) {
> +#ifdef CONFIG_VNC
> qmp_change_vnc(target, has_arg, arg, errp);
> +#else
> + error_setg(errp, QERR_FEATURE_DISABLED, "vnc");
> +#endif
> } else {
> qmp_blockdev_change_medium(true, device, false, NULL, target,
> has_arg, arg, false, 0, errp);
> diff --git a/tests/test-crypto-cipher.c b/tests/test-crypto-cipher.c
> index 07fa2fa616..5980b27389 100644
> --- a/tests/test-crypto-cipher.c
> +++ b/tests/test-crypto-cipher.c
> @@ -149,6 +149,7 @@ static QCryptoCipherTestData test_data[] = {
> "39f23369a9d9bacfa530e26304231461"
> "b2eb05e2c39be9fcda6c19078c6a9d1b",
> },
> +#ifdef CONFIG_VNC
> {
> .path = "/crypto/cipher/des-rfb-ecb-56",
> .alg = QCRYPTO_CIPHER_ALG_DES_RFB,
> @@ -165,6 +166,7 @@ static QCryptoCipherTestData test_data[] = {
> "ffd29f1bb5596ad94ea2d8e6196b7f09"
> "30d8ed0bf2773af36dd82a6280c20926",
> },
> +#endif
> #if defined(CONFIG_NETTLE) || defined(CONFIG_GCRYPT)
> {
> /* Borrowed from linux-kernel crypto/testmgr.h */
> diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
> index 4ab7fcee98..aece8c5999 100644
> --- a/hmp-commands-info.hx
> +++ b/hmp-commands-info.hx
> @@ -420,6 +420,7 @@ STEXI
> Show which guest mouse is receiving events.
> ETEXI
>
> +#if defined(CONFIG_VNC)
> {
> .name = "vnc",
> .args_type = "",
> @@ -427,6 +428,7 @@ ETEXI
> .help = "show the vnc server status",
> .cmd = hmp_info_vnc,
> },
> +#endif
>
> STEXI
> @item info vnc
I should mention at this point: the resulting change to generated code
is lovely :)
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 37/50] qapi: add conditions to SPICE type/commands/events on the schema
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 37/50] qapi: add conditions to SPICE " Marc-André Lureau
@ 2017-12-13 14:17 ` Markus Armbruster
0 siblings, 0 replies; 118+ messages in thread
From: Markus Armbruster @ 2017-12-13 14:17 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, Dr. David Alan Gilbert, Gerd Hoffmann, Paolo Bonzini
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Add #if defined(CONFIG_SPICE) in generated code, and adjust the
> qmp/hmp code accordingly.
I'd like to see a description of how this affects QMP and HMP, like the
one in the previous patch.
Are there any occurrences of SPICE in the schema that aren't made
conditional by this patch?
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> qapi/char.json | 10 ++++++----
> qapi/ui.json | 30 ++++++++++++++++++++----------
> monitor.c | 3 ---
> qmp.c | 16 ----------------
> 4 files changed, 26 insertions(+), 33 deletions(-)
>
> diff --git a/qapi/char.json b/qapi/char.json
> index ae19dcd1ed..7fa1762ae5 100644
> --- a/qapi/char.json
> +++ b/qapi/char.json
> @@ -318,7 +318,8 @@
> # Since: 1.5
> ##
> { 'struct': 'ChardevSpiceChannel', 'data': { 'type' : 'str' },
> - 'base': 'ChardevCommon' }
> + 'base': 'ChardevCommon',
> + 'if': 'defined(CONFIG_SPICE)' }
>
> ##
> # @ChardevSpicePort:
> @@ -330,7 +331,8 @@
> # Since: 1.5
> ##
> { 'struct': 'ChardevSpicePort', 'data': { 'fqdn' : 'str' },
> - 'base': 'ChardevCommon' }
> + 'base': 'ChardevCommon',
> + 'if': 'defined(CONFIG_SPICE)' }
>
> ##
> # @ChardevVC:
> @@ -384,8 +386,8 @@
> 'testdev': 'ChardevCommon',
> 'stdio' : 'ChardevStdio',
> 'console': 'ChardevCommon',
> - 'spicevmc' : 'ChardevSpiceChannel',
> - 'spiceport' : 'ChardevSpicePort',
> + 'spicevmc' : { 'type': 'ChardevSpiceChannel', 'if': 'defined(CONFIG_SPICE)' },
> + 'spiceport' : { 'type': 'ChardevSpicePort', 'if': 'defined(CONFIG_SPICE)' },
> 'vc' : 'ChardevVC',
> 'ringbuf': 'ChardevRingbuf',
> # next one is just for compatibility
> diff --git a/qapi/ui.json b/qapi/ui.json
> index 4b573d214b..daa4168c14 100644
> --- a/qapi/ui.json
> +++ b/qapi/ui.json
> @@ -110,7 +110,8 @@
> { 'struct': 'SpiceBasicInfo',
> 'data': { 'host': 'str',
> 'port': 'str',
> - 'family': 'NetworkAddressFamily' } }
> + 'family': 'NetworkAddressFamily' },
> + 'if': 'defined(CONFIG_SPICE)' }
>
> ##
> # @SpiceServerInfo:
> @@ -123,7 +124,8 @@
> ##
> { 'struct': 'SpiceServerInfo',
> 'base': 'SpiceBasicInfo',
> - 'data': { '*auth': 'str' } }
> + 'data': { '*auth': 'str' },
> + 'if': 'defined(CONFIG_SPICE)' }
>
> ##
> # @SpiceChannel:
> @@ -148,7 +150,8 @@
> { 'struct': 'SpiceChannel',
> 'base': 'SpiceBasicInfo',
> 'data': {'connection-id': 'int', 'channel-type': 'int', 'channel-id': 'int',
> - 'tls': 'bool'} }
> + 'tls': 'bool'},
> + 'if': 'defined(CONFIG_SPICE)' }
>
> ##
> # @SpiceQueryMouseMode:
> @@ -167,7 +170,8 @@
> # Since: 1.1
> ##
> { 'enum': 'SpiceQueryMouseMode',
> - 'data': [ 'client', 'server', 'unknown' ] }
> + 'data': [ 'client', 'server', 'unknown' ],
> + 'if': 'defined(CONFIG_SPICE)' }
>
> ##
> # @SpiceInfo:
> @@ -204,7 +208,8 @@
> { 'struct': 'SpiceInfo',
> 'data': {'enabled': 'bool', 'migrated': 'bool', '*host': 'str', '*port': 'int',
> '*tls-port': 'int', '*auth': 'str', '*compiled-version': 'str',
> - 'mouse-mode': 'SpiceQueryMouseMode', '*channels': ['SpiceChannel']} }
> + 'mouse-mode': 'SpiceQueryMouseMode', '*channels': ['SpiceChannel']},
> + 'if': 'defined(CONFIG_SPICE)' }
>
> ##
> # @query-spice:
> @@ -249,7 +254,8 @@
> # }
> #
> ##
> -{ 'command': 'query-spice', 'returns': 'SpiceInfo' }
> +{ 'command': 'query-spice', 'returns': 'SpiceInfo',
> + 'if': 'defined(CONFIG_SPICE)' }
>
> ##
> # @SPICE_CONNECTED:
> @@ -274,7 +280,8 @@
> ##
> { 'event': 'SPICE_CONNECTED',
> 'data': { 'server': 'SpiceBasicInfo',
> - 'client': 'SpiceBasicInfo' } }
> + 'client': 'SpiceBasicInfo' },
> + 'if': 'defined(CONFIG_SPICE)' }
>
> ##
> # @SPICE_INITIALIZED:
> @@ -302,7 +309,8 @@
> ##
> { 'event': 'SPICE_INITIALIZED',
> 'data': { 'server': 'SpiceServerInfo',
> - 'client': 'SpiceChannel' } }
> + 'client': 'SpiceChannel' },
> + 'if': 'defined(CONFIG_SPICE)' }
>
> ##
> # @SPICE_DISCONNECTED:
> @@ -327,7 +335,8 @@
> ##
> { 'event': 'SPICE_DISCONNECTED',
> 'data': { 'server': 'SpiceBasicInfo',
> - 'client': 'SpiceBasicInfo' } }
> + 'client': 'SpiceBasicInfo' },
> + 'if': 'defined(CONFIG_SPICE)' }
>
> ##
> # @SPICE_MIGRATE_COMPLETED:
> @@ -342,7 +351,8 @@
> # "event": "SPICE_MIGRATE_COMPLETED" }
> #
> ##
> -{ 'event': 'SPICE_MIGRATE_COMPLETED' }
> +{ 'event': 'SPICE_MIGRATE_COMPLETED',
> + 'if': 'defined(CONFIG_SPICE)' }
>
> ##
> # == VNC
> diff --git a/monitor.c b/monitor.c
> index 5685697f59..135a1e0821 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -970,9 +970,6 @@ static void qmp_query_qmp_schema(QDict *qdict, QObject **ret_data,
> */
> static void qmp_unregister_commands_hack(void)
> {
> -#ifndef CONFIG_SPICE
> - qmp_unregister_command(&qmp_commands, "query-spice");
> -#endif
> #ifndef CONFIG_REPLICATION
> qmp_unregister_command(&qmp_commands, "xen-set-replication");
> qmp_unregister_command(&qmp_commands, "query-xen-replication-status");
> diff --git a/qmp.c b/qmp.c
> index 2c90dacb56..90816ba283 100644
> --- a/qmp.c
> +++ b/qmp.c
> @@ -130,22 +130,6 @@ void qmp_cpu_add(int64_t id, Error **errp)
> }
> }
>
> -#ifndef CONFIG_SPICE
> -/*
> - * qmp-commands.hx ensures that QMP command query-spice exists only
> - * #ifdef CONFIG_SPICE. Necessary for an accurate query-commands
> - * result. However, the QAPI schema is blissfully unaware of that,
> - * and the QAPI code generator happily generates a dead
> - * qmp_marshal_query_spice() that calls qmp_query_spice(). Provide it
> - * one, or else linking fails. FIXME Educate the QAPI schema on
> - * CONFIG_SPICE.
> - */
> -SpiceInfo *qmp_query_spice(Error **errp)
> -{
> - abort();
> -};
> -#endif
> -
> void qmp_cont(Error **errp)
> {
> BlockBackend *blk;
Hmm, shouldn't you compile out "info spice", like you did for "info vnc"
in the previous patch?
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 38/50] qapi: add conditions to REPLICATION type/commands on the schema
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 38/50] qapi: add conditions to REPLICATION type/commands " Marc-André Lureau
@ 2017-12-13 14:19 ` Markus Armbruster
0 siblings, 0 replies; 118+ messages in thread
From: Markus Armbruster @ 2017-12-13 14:19 UTC (permalink / raw)
To: Marc-André Lureau
Cc: qemu-devel, zhanghailiang, Juan Quintela, Dr. David Alan Gilbert
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Add #if defined(CONFIG_REPLICATION) in generated code, and adjust the
> code accordingly.
>
> Made conditional:
>
> * xen-set-replication, query-xen-replication-status,
> xen-colo-do-checkpoint
>
> Before the patch, we first register the commands unconditionally in
> generated code (requires a stub), then conditionally unregister in
> qmp_unregister_commands_hack().
>
> Afterwards, we register only when CONFIG_REPLICATION. The command
> fails exactly the same, with CommandNotFound.
>
> Improvement, because now query-qmp-schema is accurate, and we're one
> step close to killing qmp_unregister_commands_hack().
s/close/closer/
>
> * enum BlockdevDriver value "replication" in command blockdev-add
>
> As well as enum BlockdevDriver value @replication BlockdevOptions
Missing a comma after @replication?
> variant @replication, BlockdevOptionsReplication,
> BlockdevOptionsReplicationMode.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> qapi/block-core.json | 15 ++++++++++-----
> qapi/migration.json | 12 ++++++++----
> migration/colo.c | 16 ++++------------
> monitor.c | 5 -----
> 4 files changed, 22 insertions(+), 26 deletions(-)
>
> diff --git a/qapi/block-core.json b/qapi/block-core.json
> index bb11815608..6f897cf157 100644
> --- a/qapi/block-core.json
> +++ b/qapi/block-core.json
> @@ -2232,8 +2232,10 @@
> 'dmg', 'file', 'ftp', 'ftps', 'gluster', 'host_cdrom',
> 'host_device', 'http', 'https', 'iscsi', 'luks', 'nbd', 'nfs',
> 'null-aio', 'null-co', 'parallels', 'qcow', 'qcow2', 'qed',
> - 'quorum', 'raw', 'rbd', 'replication', 'sheepdog', 'ssh',
> - 'throttle', 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat', 'vxhs' ] }
> + 'quorum', 'raw', 'rbd',
> + { 'name': 'replication', 'if': 'defined(CONFIG_REPLICATION)' },
> + 'sheepdog', 'ssh', 'throttle',
> + 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat', 'vxhs' ] }
>
> ##
> # @BlockdevOptionsFile:
> @@ -2855,7 +2857,8 @@
> #
> # Since: 2.9
> ##
> -{ 'enum' : 'ReplicationMode', 'data' : [ 'primary', 'secondary' ] }
> +{ 'enum' : 'ReplicationMode', 'data' : [ 'primary', 'secondary' ],
> + 'if': 'defined(CONFIG_REPLICATION)' }
>
> ##
> # @BlockdevOptionsReplication:
> @@ -2873,7 +2876,8 @@
> { 'struct': 'BlockdevOptionsReplication',
> 'base': 'BlockdevOptionsGenericFormat',
> 'data': { 'mode': 'ReplicationMode',
> - '*top-id': 'str' } }
> + '*top-id': 'str' },
> + 'if': 'defined(CONFIG_REPLICATION)' }
>
> ##
> # @NFSTransport:
> @@ -3168,7 +3172,8 @@
> 'quorum': 'BlockdevOptionsQuorum',
> 'raw': 'BlockdevOptionsRaw',
> 'rbd': 'BlockdevOptionsRbd',
> - 'replication':'BlockdevOptionsReplication',
> + 'replication': { 'type': 'BlockdevOptionsReplication',
> + 'if': 'defined(CONFIG_REPLICATION)' },
> 'sheepdog': 'BlockdevOptionsSheepdog',
> 'ssh': 'BlockdevOptionsSsh',
> 'throttle': 'BlockdevOptionsThrottle',
> diff --git a/qapi/migration.json b/qapi/migration.json
> index ee2b3b8733..44d2ef9c94 100644
> --- a/qapi/migration.json
> +++ b/qapi/migration.json
> @@ -1034,7 +1034,8 @@
> # Since: 2.9
> ##
> { 'command': 'xen-set-replication',
> - 'data': { 'enable': 'bool', 'primary': 'bool', '*failover' : 'bool' } }
> + 'data': { 'enable': 'bool', 'primary': 'bool', '*failover' : 'bool' },
> + 'if': 'defined(CONFIG_REPLICATION)' }
>
> ##
> # @ReplicationStatus:
> @@ -1049,7 +1050,8 @@
> # Since: 2.9
> ##
> { 'struct': 'ReplicationStatus',
> - 'data': { 'error': 'bool', '*desc': 'str' } }
> + 'data': { 'error': 'bool', '*desc': 'str' },
> + 'if': 'defined(CONFIG_REPLICATION)' }
>
> ##
> # @query-xen-replication-status:
> @@ -1066,7 +1068,8 @@
> # Since: 2.9
> ##
> { 'command': 'query-xen-replication-status',
> - 'returns': 'ReplicationStatus' }
> + 'returns': 'ReplicationStatus',
> + 'if': 'defined(CONFIG_REPLICATION)' }
>
> ##
> # @xen-colo-do-checkpoint:
> @@ -1082,4 +1085,5 @@
> #
> # Since: 2.9
> ##
> -{ 'command': 'xen-colo-do-checkpoint' }
> +{ 'command': 'xen-colo-do-checkpoint',
> + 'if': 'defined(CONFIG_REPLICATION)' }
> diff --git a/migration/colo.c b/migration/colo.c
> index dee3aa8bf7..010c9e02e8 100644
> --- a/migration/colo.c
> +++ b/migration/colo.c
> @@ -22,7 +22,9 @@
> #include "trace.h"
> #include "qemu/error-report.h"
> #include "migration/failover.h"
> +#ifdef CONFIG_REPLICATION
> #include "replication.h"
> +#endif
> #include "qmp-commands.h"
>
> static bool vmstate_loading;
> @@ -147,11 +149,11 @@ void colo_do_failover(MigrationState *s)
> }
> }
>
> +#ifdef CONFIG_REPLICATION
> void qmp_xen_set_replication(bool enable, bool primary,
> bool has_failover, bool failover,
> Error **errp)
> {
> -#ifdef CONFIG_REPLICATION
> ReplicationMode mode = primary ?
> REPLICATION_MODE_PRIMARY :
> REPLICATION_MODE_SECONDARY;
> @@ -170,14 +172,10 @@ void qmp_xen_set_replication(bool enable, bool primary,
> }
> replication_stop_all(failover, failover ? NULL : errp);
> }
> -#else
> - abort();
> -#endif
> }
>
> ReplicationStatus *qmp_query_xen_replication_status(Error **errp)
> {
> -#ifdef CONFIG_REPLICATION
> Error *err = NULL;
> ReplicationStatus *s = g_new0(ReplicationStatus, 1);
>
> @@ -192,19 +190,13 @@ ReplicationStatus *qmp_query_xen_replication_status(Error **errp)
>
> error_free(err);
> return s;
> -#else
> - abort();
> -#endif
> }
>
> void qmp_xen_colo_do_checkpoint(Error **errp)
> {
> -#ifdef CONFIG_REPLICATION
> replication_do_checkpoint_all(errp);
> -#else
> - abort();
> -#endif
> }
> +#endif
>
> static void colo_send_message(QEMUFile *f, COLOMessage msg,
> Error **errp)
> diff --git a/monitor.c b/monitor.c
> index 135a1e0821..b5ddcf8c67 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -970,11 +970,6 @@ static void qmp_query_qmp_schema(QDict *qdict, QObject **ret_data,
> */
> static void qmp_unregister_commands_hack(void)
> {
> -#ifndef CONFIG_REPLICATION
> - qmp_unregister_command(&qmp_commands, "xen-set-replication");
> - qmp_unregister_command(&qmp_commands, "query-xen-replication-status");
> - qmp_unregister_command(&qmp_commands, "xen-colo-do-checkpoint");
> -#endif
> #ifndef TARGET_I386
> qmp_unregister_command(&qmp_commands, "rtc-reset-reinjection");
> #endif
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 36/50] qapi: add conditions to VNC type/commands/events on the schema
2017-12-13 14:12 ` Markus Armbruster
@ 2017-12-13 14:20 ` Daniel P. Berrange
0 siblings, 0 replies; 118+ messages in thread
From: Daniel P. Berrange @ 2017-12-13 14:20 UTC (permalink / raw)
To: Markus Armbruster
Cc: Marc-André Lureau, qemu-devel, Dr. David Alan Gilbert,
Gerd Hoffmann
On Wed, Dec 13, 2017 at 03:12:26PM +0100, Markus Armbruster wrote:
> Cc: Daniel for his opinion on QCryptoCipherAlgorithm member des-rfb.
> > Enum made conditional:
>
> The enum isn't made conditional, only one of its values is. Suggest "
> Enumeration values made conditional:".
>
> > * QCryptoCipherAlgorithm
> >
> > # @des-rfb: RFB specific variant of single DES. Do not use except in VNC.
>
> Daniel, is this okay?
I don't think we should touch the crypto/ code at all here.
Although the VNC server is the only intended user of the des-rfb choice,
I don't really think we should make this conditional on CONFIG_VNC. It
isn't reducing the amount of code we build in any meaningful way and is
littering the crypto code with '#ifdef CONFIG_VNC' conditionals, which
harms readability and I think it is a code layering violation.
So please drop the following changes:
> > qapi/crypto.json | 3 ++-
> > crypto/cipher-builtin.c | 9 +++++++++
> > crypto/cipher-gcrypt.c | 10 ++++++++--
> > crypto/cipher-nettle.c | 14 +++++++++++---
> > crypto/cipher.c | 13 +++++++++++--
> > tests/test-crypto-cipher.c | 2 ++
Regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 39/50] qapi-commands: don't initialize command list in qmp_init_marshall()
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 39/50] qapi-commands: don't initialize command list in qmp_init_marshall() Marc-André Lureau
@ 2017-12-13 16:23 ` Markus Armbruster
0 siblings, 0 replies; 118+ messages in thread
From: Markus Armbruster @ 2017-12-13 16:23 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Michael Roth, Dr. David Alan Gilbert
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> This will let the caller add several list of commands.
What for? I guess that'll become clear later in this series.
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi-commands.py | 2 --
> monitor.c | 1 +
> qga/main.c | 1 +
> tests/test-qmp-commands.c | 1 +
> 4 files changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
> index 8af8d913b9..7455d2b8bb 100644
> --- a/scripts/qapi-commands.py
> +++ b/scripts/qapi-commands.py
> @@ -211,8 +211,6 @@ def gen_registry(registry):
>
> void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds)
> {
> - QTAILQ_INIT(cmds);
> -
> ''',
> c_prefix=c_name(prefix, protect=False))
> ret += registry
Please update qapi-code-gen.txt, too.
> diff --git a/monitor.c b/monitor.c
> index b5ddcf8c67..bf8a7685bf 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -1001,6 +1001,7 @@ void monitor_init_qmp_commands(void)
> * "qmp_capabilities", to enforce capability negotiation
> */
>
> + QTAILQ_INIT(&qmp_commands);
> qmp_init_marshal(&qmp_commands);
>
> qmp_register_command(&qmp_commands, "query-qmp-schema",
> diff --git a/qga/main.c b/qga/main.c
> index 62a62755bd..b949b1ccb0 100644
> --- a/qga/main.c
> +++ b/qga/main.c
> @@ -1360,6 +1360,7 @@ int main(int argc, char **argv)
>
> config->log_level = G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL;
>
> + QTAILQ_INIT(&ga_commands);
> qga_qmp_init_marshal(&ga_commands);
>
> init_dfl_pathnames();
> diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c
> index ad7b6e4e1d..28ce88e012 100644
> --- a/tests/test-qmp-commands.c
> +++ b/tests/test-qmp-commands.c
> @@ -283,6 +283,7 @@ int main(int argc, char **argv)
> g_test_add_func("/0.15/dealloc_types", test_dealloc_types);
> g_test_add_func("/0.15/dealloc_partial", test_dealloc_partial);
>
> + QTAILQ_INIT(&qmp_commands);
> test_qmp_init_marshal(&qmp_commands);
> g_test_run();
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 31/50] docs: document schema configuration
2017-12-13 10:41 ` Markus Armbruster
@ 2017-12-13 19:49 ` Eric Blake
0 siblings, 0 replies; 118+ messages in thread
From: Eric Blake @ 2017-12-13 19:49 UTC (permalink / raw)
To: Markus Armbruster, Marc-André Lureau; +Cc: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 2583 bytes --]
On 12/13/2017 04:41 AM, Markus Armbruster wrote:
> Cc: Eric for an additional pair of eyeballs.
>
> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>
>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>> ---
>> +
>> +Members can be exploded as dictionnary with 'type' & 'if' keys:
>
> dictionary
>
> I get what you mean by "can be exploded", but can we phrase this more
> clearly?
>
> In section "Struct types", we have
>
> A struct is a dictionary containing a single 'data' key whose value is
> a dictionary; the dictionary may be empty. This corresponds to a
> struct in C or an Object in JSON. Each value of the 'data' dictionary
> must be the name of a type, or a one-element array containing a type
> name.
>
> The part "must be the name of a type, or a one-element array containing
> a type" name is now wrong.
Maybe:
Where a member can normally be defined with a single string value as its
type, it is also possible to supply a dictionary with both 'type' and
'if' keys. The generated code will then guard the inclusion of that
member in the larger struct or command with #if IFCOND, where IFCOND is
the value of the 'if' key.
>> +
>> +{ 'struct': 'IfStruct', 'data':
>> + { 'foo': 'int',
>> + 'bar': { 'type': 'int', 'if': 'defined(IF_STRUCT_BAR)'} } }
>
> Perhaps add something like
>
> Code generated for such conditional members will be guarded with #if
> IFCOND, where IFCOND is the value of the 'if' key.
>
>
> Hmm. If enumeration documentation profits from an example, it stands to
> reason that the previous two would, too.
>
> Should we (additionally?) add examples of 'if' in section "Code
> generation"?
It makes the examples longer, but may be worthwhile.
>
>> +
>> +Please note that you are responsbile to ensure that the C code will
s/responsbile/responsible/
>> +compile with an arbitrary combination of conditions, since the
>> +generators are unable to check it at this point.
>> +
>> == Client JSON Protocol introspection ==
>>
>> Clients of a Client JSON Protocol commonly need to figure out what
>
> Do we need to update section "Client JSON Protocol introspection"?
It doesn't affect what the client can do with what it introspects, but
may indeed be worth mentioning that the presence of 'if' keys in the
schema is reflected through to the introspection output.
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3266
Virtualization: qemu.org | libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 619 bytes --]
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 32/50] qapi2texi: add 'If:' section to generated documentation
2017-12-13 12:35 ` Markus Armbruster
@ 2017-12-13 19:54 ` Eric Blake
0 siblings, 0 replies; 118+ messages in thread
From: Eric Blake @ 2017-12-13 19:54 UTC (permalink / raw)
To: Markus Armbruster, Marc-André Lureau; +Cc: qemu-devel, Michael Roth
[-- Attachment #1: Type: text/plain, Size: 1551 bytes --]
On 12/13/2017 06:35 AM, Markus Armbruster wrote:
> Cc: Eric for an additional pair of eyeballs.
>
> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>
>> The documentation is generated only once, and doesn't know C
>> pre-conditions. Add 'If:' sections for top-level entities.
>
> Is this what we want?
>
> QMP also exists only once. Should the generated qemu-qmp-ref.* document
> that instance of QMP, or should it document all potential instances of
> QMP?
>
I can go either way; it's nice to know that the binary that this copy of
documentation was bundled with only understands these terms (the binary
was compiled without HAVE_FOO, so any code guarded by HAVE_FOO doesn't
need to be documented); but that limits the usability of that
documentation to just that binary. It's also useful to have
fully-generic documentation hosted on the website, where everything is
documented (the documentation describes all possible builds of qemu
2.12, not just the one you installed), while mentioning the conditional
nature of the documented feature ("qemu in general knows about these
things; but check your particular binary by doing XYZ to learn if that
support was compiled in to your binary").
So having typed that, I think I'm leaning slightly towards documenting
everything, including conditionals, rather than trimming the document to
match the current build conditions.
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3266
Virtualization: qemu.org | libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 619 bytes --]
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 40/50] qapi: add -i/--include filename.h
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 40/50] qapi: add -i/--include filename.h Marc-André Lureau
@ 2017-12-14 13:50 ` Markus Armbruster
0 siblings, 0 replies; 118+ messages in thread
From: Markus Armbruster @ 2017-12-14 13:50 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Michael Roth
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Add a new option to add user-specified #include lines in the generated
> headers. This will help to split a schema, where one generated header
> will depend on another.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
If we need to manage includes manually, then this patch is one way to do
it. But I'm not sure we need to. Let me review the remainder of the
series before we analyze this further.
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 41/50] qapi: add a 'unit' pragma
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 41/50] qapi: add a 'unit' pragma Marc-André Lureau
@ 2017-12-14 13:54 ` Markus Armbruster
2017-12-14 14:00 ` Marc-André Lureau
2017-12-14 16:08 ` Markus Armbruster
1 sibling, 1 reply; 118+ messages in thread
From: Markus Armbruster @ 2017-12-14 13:54 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Michael Roth
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Add a pragma that allows to tag the following expressions with a unit
> name. By default, an expression has no unit name.
Please explain the unit name's intended purpose.
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi.py | 9 ++++++++-
> docs/devel/qapi-code-gen.txt | 3 +++
> 2 files changed, 11 insertions(+), 1 deletion(-)
>
> diff --git a/scripts/qapi.py b/scripts/qapi.py
> index eb4ffdc06d..1d0defd638 100644
> --- a/scripts/qapi.py
> +++ b/scripts/qapi.py
> @@ -279,10 +279,12 @@ class QAPISchemaParser(object):
> self.docs = []
> self.cur_doc = None
> self.accept()
> + self.unit = None
>
> while self.tok is not None:
> info = {'file': fname, 'line': self.line,
> - 'parent': self.incl_info}
> + 'parent': self.incl_info,
> + 'unit': self.unit}
> if self.tok == '#':
> self.reject_expr_doc()
> self.cur_doc = self.get_doc(info)
> @@ -371,6 +373,11 @@ class QAPISchemaParser(object):
> "Pragma name-case-whitelist must be"
> " a list of strings")
> name_case_whitelist = value
> + elif name == 'unit':
> + if not isinstance(value, str):
> + raise QAPISemError(info,
> + "Pragma 'unit' must be string")
> + self.unit = value
> else:
> raise QAPISemError(info, "Unknown pragma '%s'" % name)
>
> diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt
> index 24fc6f74ee..37a27cd9d7 100644
> --- a/docs/devel/qapi-code-gen.txt
> +++ b/docs/devel/qapi-code-gen.txt
> @@ -326,6 +326,9 @@ violate the rules on permitted return types. Default is none.
> Pragma 'name-case-whitelist' takes a list of names that may violate
> rules on use of upper- vs. lower-case letters. Default is none.
>
> +Pragma 'unit' takes a string value. It will set the unit name for the
> +following expressions in the schema. Most code generator can filter
> +based on a unit name. Default is none.
Do you mean "most code generators"?
What does "filtering" mean?
>
> === Struct types ===
Humor me: put two spaces after a sentence-ending period.
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 41/50] qapi: add a 'unit' pragma
2017-12-14 13:54 ` Markus Armbruster
@ 2017-12-14 14:00 ` Marc-André Lureau
2017-12-14 14:33 ` Markus Armbruster
0 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2017-12-14 14:00 UTC (permalink / raw)
To: Markus Armbruster; +Cc: QEMU, Michael Roth
Hi
On Thu, Dec 14, 2017 at 2:54 PM, Markus Armbruster <armbru@redhat.com> wrote:
> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>
>> Add a pragma that allows to tag the following expressions with a unit
>> name. By default, an expression has no unit name.
>
> Please explain the unit name's intended purpose.
>
It's syccintly explained in the doc.
>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>> ---
>> scripts/qapi.py | 9 ++++++++-
>> docs/devel/qapi-code-gen.txt | 3 +++
>> 2 files changed, 11 insertions(+), 1 deletion(-)
>>
>> diff --git a/scripts/qapi.py b/scripts/qapi.py
>> index eb4ffdc06d..1d0defd638 100644
>> --- a/scripts/qapi.py
>> +++ b/scripts/qapi.py
>> @@ -279,10 +279,12 @@ class QAPISchemaParser(object):
>> self.docs = []
>> self.cur_doc = None
>> self.accept()
>> + self.unit = None
>>
>> while self.tok is not None:
>> info = {'file': fname, 'line': self.line,
>> - 'parent': self.incl_info}
>> + 'parent': self.incl_info,
>> + 'unit': self.unit}
>> if self.tok == '#':
>> self.reject_expr_doc()
>> self.cur_doc = self.get_doc(info)
>> @@ -371,6 +373,11 @@ class QAPISchemaParser(object):
>> "Pragma name-case-whitelist must be"
>> " a list of strings")
>> name_case_whitelist = value
>> + elif name == 'unit':
>> + if not isinstance(value, str):
>> + raise QAPISemError(info,
>> + "Pragma 'unit' must be string")
>> + self.unit = value
>> else:
>> raise QAPISemError(info, "Unknown pragma '%s'" % name)
>>
>> diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt
>> index 24fc6f74ee..37a27cd9d7 100644
>> --- a/docs/devel/qapi-code-gen.txt
>> +++ b/docs/devel/qapi-code-gen.txt
>> @@ -326,6 +326,9 @@ violate the rules on permitted return types. Default is none.
>> Pragma 'name-case-whitelist' takes a list of names that may violate
>> rules on use of upper- vs. lower-case letters. Default is none.
>>
>> +Pragma 'unit' takes a string value. It will set the unit name for the
>> +following expressions in the schema. Most code generator can filter
>> +based on a unit name. Default is none.
>
> Do you mean "most code generators"?
The qapi code/doc generators.
>
> What does "filtering" mean?
To be able to select a subset of expressions based on the unit name.
>>
>> === Struct types ===
>
> Humor me: put two spaces after a sentence-ending period.
>
I don't get what you mean.
thanks
--
Marc-André Lureau
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 41/50] qapi: add a 'unit' pragma
2017-12-14 14:00 ` Marc-André Lureau
@ 2017-12-14 14:33 ` Markus Armbruster
0 siblings, 0 replies; 118+ messages in thread
From: Markus Armbruster @ 2017-12-14 14:33 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: QEMU, Michael Roth
Marc-André Lureau <marcandre.lureau@gmail.com> writes:
> Hi
>
> On Thu, Dec 14, 2017 at 2:54 PM, Markus Armbruster <armbru@redhat.com> wrote:
>> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>>
>>> Add a pragma that allows to tag the following expressions with a unit
>>> name. By default, an expression has no unit name.
>>
>> Please explain the unit name's intended purpose.
>>
>
> It's syccintly explained in the doc.
The commit message should state the patch's purpose. When the patch
adds documentation, and you'd rather not duplicate it in the commit
message, a short summary plus a pointer there may do.
>>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>>> ---
>>> scripts/qapi.py | 9 ++++++++-
>>> docs/devel/qapi-code-gen.txt | 3 +++
>>> 2 files changed, 11 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/scripts/qapi.py b/scripts/qapi.py
>>> index eb4ffdc06d..1d0defd638 100644
>>> --- a/scripts/qapi.py
>>> +++ b/scripts/qapi.py
>>> @@ -279,10 +279,12 @@ class QAPISchemaParser(object):
>>> self.docs = []
>>> self.cur_doc = None
>>> self.accept()
>>> + self.unit = None
>>>
>>> while self.tok is not None:
>>> info = {'file': fname, 'line': self.line,
>>> - 'parent': self.incl_info}
>>> + 'parent': self.incl_info,
>>> + 'unit': self.unit}
>>> if self.tok == '#':
>>> self.reject_expr_doc()
>>> self.cur_doc = self.get_doc(info)
>>> @@ -371,6 +373,11 @@ class QAPISchemaParser(object):
>>> "Pragma name-case-whitelist must be"
>>> " a list of strings")
>>> name_case_whitelist = value
>>> + elif name == 'unit':
>>> + if not isinstance(value, str):
>>> + raise QAPISemError(info,
>>> + "Pragma 'unit' must be string")
>>> + self.unit = value
>>> else:
>>> raise QAPISemError(info, "Unknown pragma '%s'" % name)
>>>
>>> diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt
>>> index 24fc6f74ee..37a27cd9d7 100644
>>> --- a/docs/devel/qapi-code-gen.txt
>>> +++ b/docs/devel/qapi-code-gen.txt
>>> @@ -326,6 +326,9 @@ violate the rules on permitted return types. Default is none.
>>> Pragma 'name-case-whitelist' takes a list of names that may violate
>>> rules on use of upper- vs. lower-case letters. Default is none.
>>>
>>> +Pragma 'unit' takes a string value. It will set the unit name for the
>>> +following expressions in the schema. Most code generator can filter
>>> +based on a unit name. Default is none.
>>
>> Do you mean "most code generators"?
>
> The qapi code/doc generators.
So plural is intended. Easy enough to fix.
>>
>> What does "filtering" mean?
>
> To be able to select a subset of expressions based on the unit name.
Let's spell that out.
>>>
>>> === Struct types ===
>>
>> Humor me: put two spaces after a sentence-ending period.
>>
>
> I don't get what you mean.
This sentence ends with a period, which is followed by two spaces. This
sentence is followed by just one space. I prefer two. A few
inconsistencies have crept into this file over time, let's not add more.
All clear now?
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 41/50] qapi: add a 'unit' pragma
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 41/50] qapi: add a 'unit' pragma Marc-André Lureau
2017-12-14 13:54 ` Markus Armbruster
@ 2017-12-14 16:08 ` Markus Armbruster
1 sibling, 0 replies; 118+ messages in thread
From: Markus Armbruster @ 2017-12-14 16:08 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Michael Roth
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Add a pragma that allows to tag the following expressions with a unit
> name. By default, an expression has no unit name.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi.py | 9 ++++++++-
> docs/devel/qapi-code-gen.txt | 3 +++
> 2 files changed, 11 insertions(+), 1 deletion(-)
>
> diff --git a/scripts/qapi.py b/scripts/qapi.py
> index eb4ffdc06d..1d0defd638 100644
> --- a/scripts/qapi.py
> +++ b/scripts/qapi.py
> @@ -279,10 +279,12 @@ class QAPISchemaParser(object):
> self.docs = []
> self.cur_doc = None
> self.accept()
> + self.unit = None
>
> while self.tok is not None:
> info = {'file': fname, 'line': self.line,
> - 'parent': self.incl_info}
> + 'parent': self.incl_info,
> + 'unit': self.unit}
> if self.tok == '#':
> self.reject_expr_doc()
> self.cur_doc = self.get_doc(info)
> @@ -371,6 +373,11 @@ class QAPISchemaParser(object):
> "Pragma name-case-whitelist must be"
> " a list of strings")
> name_case_whitelist = value
> + elif name == 'unit':
> + if not isinstance(value, str):
> + raise QAPISemError(info,
> + "Pragma 'unit' must be string")
> + self.unit = value
> else:
> raise QAPISemError(info, "Unknown pragma '%s'" % name)
>
> diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt
> index 24fc6f74ee..37a27cd9d7 100644
> --- a/docs/devel/qapi-code-gen.txt
> +++ b/docs/devel/qapi-code-gen.txt
> @@ -326,6 +326,9 @@ violate the rules on permitted return types. Default is none.
> Pragma 'name-case-whitelist' takes a list of names that may violate
> rules on use of upper- vs. lower-case letters. Default is none.
>
> +Pragma 'unit' takes a string value. It will set the unit name for the
> +following expressions in the schema. Most code generator can filter
> +based on a unit name. Default is none.
>
> === Struct types ===
Test coverage?
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 42/50] qapi: add a -u/--unit option to specify which unit to visit
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 42/50] qapi: add a -u/--unit option to specify which unit to visit Marc-André Lureau
@ 2017-12-14 16:16 ` Markus Armbruster
0 siblings, 0 replies; 118+ messages in thread
From: Markus Armbruster @ 2017-12-14 16:16 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Michael Roth
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Allow to filter expressions based on unit name.
>
> By default, only default units are processed (unspecified pragma).
>
> 'all' will include all units. Anything else will filter by unit name.
You therefore can't have a unit called 'all'. Hardly a loss, but I
suspect documenting and guarding against it is more trouble than the
feature's worth.
If we want to keep it, the previous patch needs to reject { 'pragma': {
'unit': 'all' } }.
> (add a FIXME to make implicit array types use the element type unit,
> not the unit of the first expression using that array type. This isn't
> necessary for now, and I am not sure how to best do it yet)
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi.py | 14 ++++++++++++--
> scripts/qapi2texi.py | 1 +
> 2 files changed, 13 insertions(+), 2 deletions(-)
>
> diff --git a/scripts/qapi.py b/scripts/qapi.py
> index 1d0defd638..7778585819 100644
> --- a/scripts/qapi.py
> +++ b/scripts/qapi.py
> @@ -47,6 +47,9 @@ returns_whitelist = []
> # Whitelist of entities allowed to violate case conventions
> name_case_whitelist = []
>
> +# Unit to consider for the visit, 'all' for all units
> +visit_unit = None
> +
> enum_types = {}
> struct_types = {}
> union_types = {}
> @@ -1796,6 +1799,10 @@ class QAPISchema(object):
> def visit(self, visitor):
> visitor.visit_begin(self)
> for (name, entity) in sorted(self._entity_dict.items()):
> + # FIXME: implicit array types should use element type unit
> + unit = entity.info and entity.info.get('unit')
@unit is str, ensured by QAPISchemaParser.
> + if visit_unit != 'all' and visit_unit != unit:
> + continue
If visit_unit is still None, we don't visit anything.
> if visitor.visit_needed(entity):
> entity.visit(visitor)
> visitor.visit_end()
> @@ -2103,13 +2110,14 @@ def parse_command_line(extra_options='', extra_long_options=[]):
>
> try:
> opts, args = getopt.gnu_getopt(sys.argv[1:],
> - 'chp:o:i:' + extra_options,
> + 'chp:o:u:i:' + extra_options,
> ['source', 'header', 'prefix=', 'output-dir=',
> - 'include='] + extra_long_options)
> + 'unit=', 'include='] + extra_long_options)
> except getopt.GetoptError as err:
> print >>sys.stderr, "%s: %s" % (sys.argv[0], str(err))
> sys.exit(1)
>
> + global visit_unit
> output_dir = ''
> prefix = ''
> do_c = False
> @@ -2129,6 +2137,8 @@ def parse_command_line(extra_options='', extra_long_options=[]):
> prefix = a
> elif o in ('-o', '--output-dir'):
> output_dir = a + '/'
> + elif o in ('-u', '--unit'):
> + visit_unit = a
> elif o in ('-c', '--source'):
> do_c = True
> elif o in ('-h', '--header'):
If the user doesn't give -u, @visit_unit remains None, and
QAPISchema.visit() won't visit anything.
I recommend to dumb this down as follows. No special unit name 'all'.
If you want all, don't specify -u. @visit_unit remains None then.
> diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py
> index 4e7b1cda87..6c856d4cb7 100755
> --- a/scripts/qapi2texi.py
> +++ b/scripts/qapi2texi.py
> @@ -293,6 +293,7 @@ def main(argv):
> print >>sys.stderr, "%s: need exactly 1 argument: SCHEMA" % argv[0]
> sys.exit(1)
>
> + qapi.visit_unit = 'all'
> schema = qapi.QAPISchema(argv[1])
> if not qapi.doc_required:
> print >>sys.stderr, ("%s: need pragma 'doc-required' "
Bonus: this hunk won't be needed then, because the default value just
works.
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 43/50] build-sys: move qmp-introspect per target
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 43/50] build-sys: move qmp-introspect per target Marc-André Lureau
@ 2017-12-14 16:30 ` Markus Armbruster
2018-01-11 21:32 ` Marc-André Lureau
0 siblings, 1 reply; 118+ messages in thread
From: Markus Armbruster @ 2017-12-14 16:30 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Michael Roth
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> The following patches are going to introduce per-target #ifdef, and
> but the introspection data is generated only once, and must thus be
> built with the target.
"and but"?
> Drop "do_test_visitor_in_qmp_introspect(&&qmp_schema_qlit)" since it
s/&&/&/
> is no longer in a common object, and covered by "query-qmp-schema
> test" instead.
Do you mean test /x86_64/qmp/query-qmp-schema of tests/qmp-test.c?
That test tests significantly less. It runs the command, tests it
succeeds and returns something. The test you remove additionally tests
the returned value conforms to the schema, by passing it to
visit_type_SchemaInfoList().
Perhaps we can enhance the test you keep to avoid this loss.
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 44/50] build-sys: add a target schema
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 44/50] build-sys: add a target schema Marc-André Lureau
@ 2017-12-14 16:34 ` Markus Armbruster
2018-01-11 21:32 ` Marc-André Lureau
0 siblings, 1 reply; 118+ messages in thread
From: Markus Armbruster @ 2017-12-14 16:34 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, Dr. David Alan Gilbert
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> This schema is going to contain target-specific commands/events &
> types, that can be conditionnally guarded with poisoned defines. To
> filter it out by default, set the unit name to 'target'.
>
> And new rules to compile this unit generated files per-target.
>
> Use the "-u all" options for the introspection schema, since it is
> generated as a single file and must contain all definitions.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> qapi-schema.json | 1 +
> qapi/target.json | 3 +++
> monitor.c | 2 ++
> Makefile | 29 ++++++++++++++++++++++++++++-
> Makefile.target | 2 ++
> 5 files changed, 36 insertions(+), 1 deletion(-)
> create mode 100644 qapi/target.json
>
> diff --git a/qapi-schema.json b/qapi-schema.json
> index f3af2cb851..42b6aebddb 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -92,6 +92,7 @@
> { 'include': 'qapi/transaction.json' }
> { 'include': 'qapi/trace.json' }
> { 'include': 'qapi/introspect.json' }
> +{ 'include': 'qapi/target.json' }
>
> ##
> # = Miscellanea
> diff --git a/qapi/target.json b/qapi/target.json
> new file mode 100644
> index 0000000000..e9644f52c2
> --- /dev/null
> +++ b/qapi/target.json
> @@ -0,0 +1,3 @@
> +# -*- Mode: Python -*-
> +
> +{ 'pragma': { 'unit': 'target' } }
> diff --git a/monitor.c b/monitor.c
> index bf8a7685bf..af4eaeca5e 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -68,6 +68,7 @@
> #include "exec/exec-all.h"
> #include "qemu/log.h"
> #include "qmp-commands.h"
> +#include "target-qmp-commands.h"
> #include "hmp.h"
> #include "qemu/thread.h"
> #include "block/qapi.h"
> @@ -1003,6 +1004,7 @@ void monitor_init_qmp_commands(void)
>
> QTAILQ_INIT(&qmp_commands);
> qmp_init_marshal(&qmp_commands);
> + target_qmp_init_marshal(&qmp_commands);
>
> qmp_register_command(&qmp_commands, "query-qmp-schema",
> qmp_query_qmp_schema,
> diff --git a/Makefile b/Makefile
> index 337a1f6f9b..7356b4e7b7 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -54,6 +54,8 @@ include $(SRC_PATH)/rules.mak
> GENERATED_FILES = qemu-version.h config-host.h qemu-options.def
> GENERATED_FILES += qmp-commands.h qapi-types.h qapi-visit.h qapi-event.h
> GENERATED_FILES += qmp-marshal.c qapi-types.c qapi-visit.c qapi-event.c
> +GENERATED_FILES += target-qmp-commands.h target-qapi-types.h target-qapi-visit.h target-qapi-event.h
> +GENERATED_FILES += target-qmp-marshal.c target-qapi-types.c target-qapi-visit.c target-qapi-event.c
> GENERATED_FILES += qmp-introspect.h
> GENERATED_FILES += qmp-introspect.c
>
> @@ -418,6 +420,7 @@ qapi-modules = $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi/common.json \
> $(SRC_PATH)/qapi/rocker.json \
> $(SRC_PATH)/qapi/run-state.json \
> $(SRC_PATH)/qapi/sockets.json \
> + $(SRC_PATH)/qapi/target.json \
> $(SRC_PATH)/qapi/tpm.json \
> $(SRC_PATH)/qapi/trace.json \
> $(SRC_PATH)/qapi/transaction.json \
> @@ -443,10 +446,34 @@ $(qapi-modules) $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
> $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py \
> $(gen-out-type) -o "." $<, \
> "GEN","$@")
> +
> +target-qapi-types.c target-qapi-types.h :\
> +$(qapi-modules) $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
> + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py \
> + -i qapi-types.h \
> + $(gen-out-type) -p target- -u target $<, \
> + "GEN","$@")
> +target-qapi-visit.c target-qapi-visit.h :\
> +$(qapi-modules) $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py)
> + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py \
> + -i qapi-visit.h \
> + $(gen-out-type) -p target- -u target $<, \
> + "GEN","$@")
> +target-qapi-event.c target-qapi-event.h :\
> +$(qapi-modules) $(SRC_PATH)/scripts/qapi-event.py $(qapi-py)
> + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-event.py \
> + $(gen-out-type) -p target- -u target $<, \
> + "GEN","$@")
> +target-qmp-commands.h target-qmp-marshal.c :\
> +$(qapi-modules) $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
> + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py \
> + $(gen-out-type) -p target- -u target $<, \
> + "GEN","$@")
> +
> qmp-introspect.h qmp-introspect.c :\
> $(qapi-modules) $(SRC_PATH)/scripts/qapi-introspect.py $(qapi-py)
> $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-introspect.py \
> - $(gen-out-type) -o "." $<, \
> + $(gen-out-type) -o "." -u all $<, \
> "GEN","$@")
>
Let's see whether I understand how this works. Without -u (not fully
visible in the diff), we get everything but the target-specific stuff.
With -u target, we get just the target-specific stuff. With -u all, we
get everything. Correct?
> QGALIB_GEN=$(addprefix qga/qapi-generated/, qga-qapi-types.h qga-qapi-visit.h qga-qmp-commands.h)
> diff --git a/Makefile.target b/Makefile.target
> index 0d28ed1df0..e44a3847d3 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -157,6 +157,8 @@ endif
>
> GENERATED_FILES += hmp-commands.h hmp-commands-info.h
>
> +obj-y += target-qapi-types.o target-qapi-visit.o
> +obj-y += target-qapi-event.o target-qmp-marshal.o
> obj-y += qmp-introspect.o
>
> endif # CONFIG_SOFTMMU
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 00/50] Hi,
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
` (50 preceding siblings ...)
2017-09-11 11:54 ` [Qemu-devel] [PATCH v3 00/50] Hi, no-reply
@ 2017-12-18 13:14 ` Markus Armbruster
51 siblings, 0 replies; 118+ messages in thread
From: Markus Armbruster @ 2017-12-18 13:14 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> In order to clean-up some hacks in qapi (having to unregister commands
> at runtime), I proposed a "[PATCH v5 02/20] qapi.py: add a simple #ifdef condition"
>
> (see http://lists.gnu.org/archive/html/qemu-devel/2016-08/msg03106.html).
>
> However, we decided to drop that patch from the series and solve the
> problem later. The main issues were:
> - the syntax was awkward to the JSON schema and documentation
> - the evaluation of the condition was done in the qapi scripts, with
> very limited capability
> - each target/config would need different generated files.
>
> Instead, it could defer the #if evaluation to the C-preprocessor.
>
> With this series, top-level qapi JSON entity can take 'if' keys:
>
> { 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
> 'if': 'defined(TEST_IF_STRUCT)' }
>
> Members can be exploded as dictionnary with 'type'/'if' keys:
>
> { 'struct': 'TestIfStruct', 'data':
> { 'foo': 'int',
> 'bar': { 'type': 'int', 'if': 'defined(TEST_IF_STRUCT_BAR)'} } }
>
> Enum values can be exploded as dictionnary with 'type'/'if' keys:
>
> { 'enum': 'TestIfEnum', 'data':
> [ 'foo',
> { 'name' : 'bar', 'if': 'defined(TEST_IF_ENUM_BAR)' } ] }
>
> A good benefit from having conditional schema is that introspection
> will reflect more accurately the capability of the server. Another
> benefit is that it may help to remove some dead code when disabling a
> functionality.
>
> Starting from patch "qapi: add conditions to VNC type/commands/events
> on the schema", the series demonstrate adding conditions, in order to
> remove qmp_unregister_commands_hack(). The main difference with v2, is
> the addition of a per-target schema in "build-sys: add a target
> schema". This removes the NEED_CPU_H hack, and keep most of the qapi
> files in common build.
>
> There are a lot more things we could make conditional in the QAPI
> schema, like pci/kvm/xen/numa/vde/slirp/posix/win32/vsock/lzo etc etc,
> however I am still evaluating the implication of such changes both
> externally and internally, for those interested, I can share my wip
> branch.
>
> Comments welcome,
>
> v3:
> - rebased (qlit is now merged upstream)
> - solve the per-target #ifdef problem by using a target.json
> and new qapi generated target files
> - update some commit messages based on Markus review
> - more schema error reporting
> - move the ifcond argument closer to info/doc
> - use mcgen() in gen_if()/gen_endif()
> - simplify "modify to_qlit() to take an optional suffix"
> - fix generated qlit indentation
> - fix temporary build break by merging #if types & visitors patch
> - fix some redundant condtionals generation
> - change enum visitor to take QAPISchemaMember
> - reject unknown dictionnary keys in { .., 'if': ..}
> - split qapi test visitor print() with trailing ',' trick
Things I like:
* How you add conditionals to the QAPI language
* How the generated code changes
Things I don't like so much:
* A few commit messages are just too terse
* Code and its test added in separate patches
* ifcond_decorator
I guess can either accept it, or come up with a better solution.
* Unconventional handling of sugared forms (see my review of PATCH 28).
* Addressing complilation consistency problems (see my review of PATCH
17) before addressing them by splitting off target-specific generated
files (PATCH 39..)
* Manual splitting of the generated monolith with pragma unit, -i and
-u. I guess can either accept it, or come up with a better solution.
Additionally, there are couple of minor things here and there, and a few
questions. The usual patch review business.
Overall, there's much more for me to like than to dislike :)
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 09/50] qapi: add #if/#endif helpers
2017-12-07 14:10 ` Markus Armbruster
@ 2018-01-11 21:21 ` Marc-André Lureau
0 siblings, 0 replies; 118+ messages in thread
From: Marc-André Lureau @ 2018-01-11 21:21 UTC (permalink / raw)
To: Markus Armbruster; +Cc: QEMU, Michael Roth
Hi
On Thu, Dec 7, 2017 at 3:10 PM, Markus Armbruster <armbru@redhat.com> wrote:
> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>
>> Add helpers to wrap generated code with #if/#endif lines.
>>
>> Add a function decorator that will be used to wrap visitor methods.
>> The decorator will check if code was generated before adding #if/#endif
>> lines. Used in the following patches.
>>
>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>> ---
>> scripts/qapi.py | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>> 1 file changed, 55 insertions(+)
>>
>> diff --git a/scripts/qapi.py b/scripts/qapi.py
>> index 2a8e60e975..94b735d8d6 100644
>> --- a/scripts/qapi.py
>> +++ b/scripts/qapi.py
>> @@ -1897,6 +1897,61 @@ def guardend(name):
>> name=guardname(name))
>>
>>
>> +def gen_if(ifcond):
>> + if not ifcond:
>> + return ''
>> + if isinstance(ifcond, str):
>> + ifcond = [ifcond]
>
> Perhaps we should take this normalization step in the QAPISchema
> constructors.
Yes, it's not very convenient though, I added a TODO note
>
>> + ret = ''
>> + for ifc in ifcond:
>> + ret += mcgen('''
>> +#if %(cond)s
>> +''', cond=ifc)
>> + return ret
>> +
>> +
>> +def gen_endif(ifcond):
>> + if not ifcond:
>> + return ''
>> + if isinstance(ifcond, str):
>> + ifcond = [ifcond]
>> + ret = ''
>> + for ifc in reversed(ifcond):
>> + ret += mcgen('''
>> +#endif /* %(cond)s */
>> +''', cond=ifc)
>> + return ret
>> +
>> +
>> +# Wrap a method to add #if / #endif to generated code, only if some
>> +# code was generated. The method must have an 'ifcond' argument.
>> +# self must have 'if_members' listing the attributes to wrap.
>> +def ifcond_decorator(func):
>> +
>> + def func_wrapper(self, *args, **kwargs):
>> + import inspect
>
> Is hiding imports in function a good idea?
I believe it's best to restrict the import to the scope it is being
used, especially if it's very specific to that place. Some code do
that already.
>
>> + idx = inspect.getargspec(func).args.index('ifcond')
>> + ifcond = args[idx - 1]
>> + save = {}
>> + for mem in self.if_members:
>> + save[mem] = getattr(self, mem)
>> + func(self, *args, **kwargs)
>> + for mem, val in save.items():
>> + newval = getattr(self, mem)
>> + if newval != val:
>> + assert newval.startswith(val)
>> + newval = newval[len(val):]
>> + if newval[0] == '\n':
>> + val += '\n'
>> + newval = newval[1:]
>> + val += gen_if(ifcond)
>> + val += newval
>> + val += gen_endif(ifcond)
>> + setattr(self, mem, val)
>> +
>> + return func_wrapper
>> +
>> +
>> def gen_enum_lookup(name, values, prefix=None):
>> ret = mcgen('''
>
> My gut feeling is still "too clever by half", but i'm reserving
> judgement until after review of its use, and exploration of
> alternatives.
>
Could easily be done as a follow-up.
thanks
--
Marc-André Lureau
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 15/50] qapi-types: refactor variants handling
2017-12-07 15:57 ` Markus Armbruster
@ 2018-01-11 21:22 ` Marc-André Lureau
0 siblings, 0 replies; 118+ messages in thread
From: Marc-André Lureau @ 2018-01-11 21:22 UTC (permalink / raw)
To: Markus Armbruster; +Cc: QEMU, Michael Roth
Hi
On Thu, Dec 7, 2017 at 4:57 PM, Markus Armbruster <armbru@redhat.com> wrote:
> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>
>> Generate variants objects outside gen_object(). This will allow to
>> easily wrap gen_object() with ifcond_decorator in the following patch.
>>
>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>> ---
>> scripts/qapi-types.py | 37 +++++++++++++++++++++++--------------
>> 1 file changed, 23 insertions(+), 14 deletions(-)
>>
>> diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
>> index 915786c463..2b3588267b 100644
>> --- a/scripts/qapi-types.py
>> +++ b/scripts/qapi-types.py
>> @@ -53,23 +53,27 @@ def gen_struct_members(members):
>> return ret
>>
>>
>> -def gen_object(name, base, members, variants):
>> - if name in objects_seen:
>> - return ''
>> - objects_seen.add(name)
>> -
>> +def gen_variants_objects(variants):
>> ret = ''
>> if variants:
>> for v in variants.variants:
>> if isinstance(v.type, QAPISchemaObjectType):
>> + ret += gen_variants_objects(v.type.variants)
>> ret += gen_object(v.type.name, v.type.base,
>> v.type.local_members, v.type.variants)
>> + return ret
>>
>> - ret += mcgen('''
>> +
>> +def gen_object(name, base, members, variants):
>> + if name in objects_seen:
>> + return ''
>> + objects_seen.add(name)
>> +
>> + ret = mcgen('''
>>
>> struct %(c_name)s {
>> ''',
>> - c_name=c_name(name))
>> + c_name=c_name(name))
>>
>> if base:
>> if not base.is_implicit():
>> @@ -218,11 +222,7 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
>> self.decl += gen_array(name, element_type)
>> self._gen_type_cleanup(name)
>>
>> - def visit_object_type(self, name, info, ifcond, base, members, variants):
>> - # Nothing to do for the special empty builtin
>> - if name == 'q_empty':
>> - return
>> - self._fwdecl += gen_fwd_object_or_array(name)
>> + def _gen_object(self, name, info, ifcond, base, members, variants):
>> self.decl += gen_object(name, base, members, variants)
>> if base and not base.is_implicit():
>> self.decl += gen_upcast(name, base)
>> @@ -232,10 +232,19 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
>> # implicit types won't be directly allocated/freed
>> self._gen_type_cleanup(name)
>>
>> + def visit_object_type(self, name, info, ifcond, base, members, variants):
>> + # Nothing to do for the special empty builtin
>> + if name == 'q_empty':
>> + return
>> + self._fwdecl += gen_fwd_object_or_array(name)
>> + self.decl += gen_variants_objects(variants)
>> + self._gen_object(name, info, None, base, members, variants)
>> +
>> def visit_alternate_type(self, name, info, ifcond, variants):
>> self._fwdecl += gen_fwd_object_or_array(name)
>> - self.decl += gen_object(name, None, [variants.tag_member], variants)
>> - self._gen_type_cleanup(name)
>> + self.decl += gen_variants_objects(variants)
>> + self._gen_object(name, info, None, None,
>> + [variants.tag_member], variants)
>
> Where did self._gen_type_cleanup(name) go? Hmm, I guess it's now in
> _gen_object(). Confusing.
This factors out common code that must be wrap by the same ifcond, in
the following patch.
>>
>> # If you link code generated from multiple schemata, you want only one
>> # instance of the code for built-in types. Generate it only when
>
> If I read this patch correctly, you move code from the beginning of
> gen_object() to new gen_variants_objects(), then arrange to have
> gen_variants_objects() called right before gen_object(). Correct?
>
> In old gen_object(), the code is guarded by
>
> if name in objects_seen:
> return ''
> objects_seen.add(name)
>
> In new gen_variants_objects(), it isn't. Why?
gen_variants_objects() calls gen_object() for each variants, so it
remains guarded.
--
Marc-André Lureau
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 17/50] qapi: do not define enumeration value explicitely
2017-12-08 7:50 ` Markus Armbruster
@ 2018-01-11 21:24 ` Marc-André Lureau
2018-02-02 14:43 ` Markus Armbruster
0 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2018-01-11 21:24 UTC (permalink / raw)
To: Markus Armbruster; +Cc: QEMU, Michael Roth
Hi
On Fri, Dec 8, 2017 at 8:50 AM, Markus Armbruster <armbru@redhat.com> wrote:
> Marc-André Lureau <marcandre.lureau@gmail.com> writes:
>
>> On Thu, Dec 7, 2017 at 5:23 PM, Markus Armbruster <armbru@redhat.com> wrote:
>>> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>>>
>>>> The C standard has the initial value at 0 and the subsequent values
>>>> incremented by 1. No need to set this explicitely.
>>>>
>>>> This will prevent from artificial "gaps" when compiling out some enum
>>>> values and having unnecessarily large MAX values & enums arrays.
>>>>
>>>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>>>> ---
>>>> scripts/qapi.py | 7 ++-----
>>>> 1 file changed, 2 insertions(+), 5 deletions(-)
>>>>
>>>> diff --git a/scripts/qapi.py b/scripts/qapi.py
>>>> index 94b735d8d6..074ee221a1 100644
>>>> --- a/scripts/qapi.py
>>>> +++ b/scripts/qapi.py
>>>> @@ -1985,14 +1985,11 @@ typedef enum %(c_name)s {
>>>> ''',
>>>> c_name=c_name(name))
>>>>
>>>> - i = 0
>>>> for value in enum_values:
>>>> ret += mcgen('''
>>>> - %(c_enum)s = %(i)d,
>>>> + %(c_enum)s,
>>>> ''',
>>>> - c_enum=c_enum_const(name, value, prefix),
>>>> - i=i)
>>>> - i += 1
>>>> + c_enum=c_enum_const(name, value, prefix))
>>>>
>>>> ret += mcgen('''
>>>> } %(c_name)s;
>>>
>>> Recapitulate review of v2: this risks entertaining mishaps like
>>> compiling this one
>>>
>>> typedef enum Color {
>>> COLOR_WHITE,
>>> #if defined(NEED_CPU_H)
>>> #if defined(TARGET_S390X)
>>> COLOR_BLUE,
>>> #endif /* defined(TARGET_S390X) */
>>> #endif /* defined(NEED_CPU_H) */
>>> COLOR_BLACK,
>>> } Color;
>>>
>>> in s390x-code (COLOR_BLACK = 2) and in target-independent code
>>> (COLOR_BLACK = 1), then linking the two together.
>>>
>>> Same issue for struct members and such (previous patch).
>>>
>>> What's our story on preventing disaster here?
>>>
>>> In the long run, we want to split the generated code so that
>>> target-specific and target-independent code are separate, and each part
>>> is always compiled with consistent preprocessor symbols. But I'm afraid
>>> that's not in the card right now.
>>
>> Eh, I need to refresh my memories about that series, but I think
>> that's what I did in v3
>>
>> It doesn't use the NEED_CPU_H trick. It has a seperate per-target target.json
>
> Looking... aha! target.json appears in PATCH 44 (which I haven't even
> glanced at, yet). The problem appears in PATCH 16, though. Perhaps a
> bit of patch reshuffling would do.
What problem appears in patch 16? Some code could be introduced using
NEED_CPU_H and link arch & independent code together? It is still true
after patch 44. If necessary, I can work on a split-qapi series before
the conditionals are added. But the real benefit is only apparent
after the conditional are introduced, so I am not motivated to
reorder.
>
>>> I therefore proposed the stupidest temporary stopgap that could possibly
>>> work: apply conditionals *only* to qmp-introspect.c, leave everything
>>> unconditional elsewhere.
>>
>> I don't like that idea much and I don't think we need that
>> restriction, but I need to get back to that series on some point
>> (probably after you finish the review).
>
> It's a beefy series, and it's probably best to let me review the largest
> prefix I can before we dive into discussion.
thanks
--
Marc-André Lureau
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 19/50] qapi: add 'if' to enum members
2017-12-08 8:38 ` Markus Armbruster
@ 2018-01-11 21:24 ` Marc-André Lureau
0 siblings, 0 replies; 118+ messages in thread
From: Marc-André Lureau @ 2018-01-11 21:24 UTC (permalink / raw)
To: Markus Armbruster; +Cc: QEMU, Michael Roth
Hi
On Fri, Dec 8, 2017 at 9:38 AM, Markus Armbruster <armbru@redhat.com> wrote:
> A bit more detail in the commit message would make this patch easier to
> review.
>
> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>
>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>> ---
>> scripts/qapi.py | 39 ++++++++++++++++++++++++++++-----
>> tests/Makefile.include | 1 -
>> tests/qapi-schema/enum-dict-member.err | 1 -
>> tests/qapi-schema/enum-dict-member.exit | 1 -
>> tests/qapi-schema/enum-dict-member.json | 2 --
>> tests/qapi-schema/enum-dict-member.out | 0
>> tests/qapi-schema/qapi-schema-test.json | 5 +++--
>> tests/qapi-schema/qapi-schema-test.out | 3 ++-
>> tests/qapi-schema/test-qapi.py | 2 ++
>> 9 files changed, 41 insertions(+), 13 deletions(-)
>> delete mode 100644 tests/qapi-schema/enum-dict-member.err
>> delete mode 100644 tests/qapi-schema/enum-dict-member.exit
>> delete mode 100644 tests/qapi-schema/enum-dict-member.json
>> delete mode 100644 tests/qapi-schema/enum-dict-member.out
>>
>> diff --git a/scripts/qapi.py b/scripts/qapi.py
>> index 386a577a59..1535de9ce7 100644
>> --- a/scripts/qapi.py
>> +++ b/scripts/qapi.py
>> @@ -659,6 +659,14 @@ def check_if(expr, info):
>> info, "'if' condition must be a string or a list of strings")
>>
>>
>> +def check_unknown_keys(info, dict, allowed_keys):
>> + diff = set(dict) - allowed_keys
>> + if not diff:
>> + return
>> + raise QAPISemError(info, "Dictionnary has unknown keys: %s (allowed: %s)" %
>
> s/Dictionnary/Dictionary/
ok
>
>> + (', '.join(diff), ', '.join(allowed_keys)))
>
> I'm afraid this duplicates a part of check_keys(). Could it be factored
> out?
done
>
>> +
>> +
>> def check_type(info, source, value, allow_array=False,
>> allow_dict=False, allow_optional=False,
>> allow_metas=[]):
>> @@ -739,6 +747,10 @@ def check_event(expr, info):
>> allow_metas=meta)
>>
>>
>> +def enum_get_values(expr):
>> + return [e if isinstance(e, str) else e['name'] for e in expr['data']]
>> +
>> +
>> def check_union(expr, info):
>> name = expr['union']
>> base = expr.get('base')
>> @@ -798,7 +810,7 @@ def check_union(expr, info):
>> # If the discriminator names an enum type, then all members
>> # of 'data' must also be members of the enum type.
>> if enum_define:
>> - if key not in enum_define['data']:
>> + if key not in enum_get_values(enum_define):
>> raise QAPISemError(info,
>> "Discriminator value '%s' is not found in "
>> "enum '%s'"
>> @@ -806,7 +818,7 @@ def check_union(expr, info):
>>
>> # If discriminator is user-defined, ensure all values are covered
>> if enum_define:
>> - for value in enum_define['data']:
>> + for value in enum_get_values(enum_define):
>> if value not in members.keys():
>> raise QAPISemError(info, "Union '%s' data missing '%s' branch"
>> % (name, value))
>> @@ -837,7 +849,7 @@ def check_alternate(expr, info):
>> if qtype == 'QTYPE_QSTRING':
>> enum_expr = enum_types.get(value)
>> if enum_expr:
>> - for v in enum_expr['data']:
>> + for v in enum_get_values(enum_expr):
>> if v in ['on', 'off']:
>> conflicting.add('QTYPE_QBOOL')
>> if re.match(r'[-+0-9.]', v): # lazy, could be tightened
>> @@ -865,6 +877,14 @@ def check_enum(expr, info):
>> raise QAPISemError(info,
>> "Enum '%s' requires a string for 'prefix'" % name)
>> for member in members:
>> + if isinstance(member, dict):
>> + if 'name' not in member:
>> + raise QAPISemError(info, "Dictionary member of enum '%s' must "
>> + "have a 'name' key" % name)
>> + if 'if' in member:
>> + check_if(member, info)
>> + check_unknown_keys(info, member, {'name', 'if'})
>> + member = member['name']
>> check_name(info, "Member of enum '%s'" % name, member,
>> enum_member=True)
>>
>> @@ -1280,9 +1300,11 @@ class QAPISchemaObjectType(QAPISchemaType):
>> class QAPISchemaMember(object):
>> role = 'member'
>>
>> - def __init__(self, name):
>> + def __init__(self, name, ifcond=None):
>> assert isinstance(name, str)
>> + assert ifcond is None or isinstance(ifcond, str)
>> self.name = name
>> + self.ifcond = ifcond
>> self.owner = None
>>
>> def set_owner(self, name):
>
> QAPISchemaObjectTypeMember inherits .ifcond. Peeking ahead: looks like
> it'll get used when we add conditions to object type members, PATCH
> 23ff. Okay. Mentioning it in the commit message wouldn't hurt, though.
It will *also* get used. Ok, updated commit message.
>
>> @@ -1559,7 +1581,14 @@ class QAPISchema(object):
>> qtype_values, 'QTYPE'))
>>
>> def _make_enum_members(self, values):
>> - return [QAPISchemaMember(v) for v in values]
>> + enum = []
>> + for v in values:
>> + ifcond = None
>> + if isinstance(v, dict):
>> + ifcond = v.get('if')
>> + v = v['name']
>> + enum.append(QAPISchemaMember(v, ifcond))
>
>
> I like brevity a lot, but if it's bought by assigning to a loop control
> variable, I pass. Cleaner:
>
> for v in values:
> if isinstance(v, dict):
> name = v['name']
> ifcond = v.get('if')
> else:
> name = v
> ifcond = None
> enum.append(QAPISchemaMember(name, ifcond))
>
sure
>> + return enum
>>
>> def _make_implicit_enum_type(self, name, info, ifcond, values):
>> # See also QAPISchemaObjectTypeMember._pretty_owner()
>> diff --git a/tests/Makefile.include b/tests/Makefile.include
>> index 8dac7c9083..a9f0ddbe01 100644
>> --- a/tests/Makefile.include
>> +++ b/tests/Makefile.include
>> @@ -443,7 +443,6 @@ qapi-schema += empty.json
>> qapi-schema += enum-bad-name.json
>> qapi-schema += enum-bad-prefix.json
>> qapi-schema += enum-clash-member.json
>> -qapi-schema += enum-dict-member.json
>> qapi-schema += enum-int-member.json
>> qapi-schema += enum-member-case.json
>> qapi-schema += enum-missing-data.json
>> diff --git a/tests/qapi-schema/enum-dict-member.err b/tests/qapi-schema/enum-dict-member.err
>> deleted file mode 100644
>> index 8ca146ea59..0000000000
>> --- a/tests/qapi-schema/enum-dict-member.err
>> +++ /dev/null
>> @@ -1 +0,0 @@
>> -tests/qapi-schema/enum-dict-member.json:2: Member of enum 'MyEnum' requires a string name
>> diff --git a/tests/qapi-schema/enum-dict-member.exit b/tests/qapi-schema/enum-dict-member.exit
>> deleted file mode 100644
>> index d00491fd7e..0000000000
>> --- a/tests/qapi-schema/enum-dict-member.exit
>> +++ /dev/null
>> @@ -1 +0,0 @@
>> -1
>> diff --git a/tests/qapi-schema/enum-dict-member.json b/tests/qapi-schema/enum-dict-member.json
>> deleted file mode 100644
>> index 79672e0f09..0000000000
>> --- a/tests/qapi-schema/enum-dict-member.json
>> +++ /dev/null
>> @@ -1,2 +0,0 @@
>> -# we reject any enum member that is not a string
>> -{ 'enum': 'MyEnum', 'data': [ { 'value': 'str' } ] }
>> diff --git a/tests/qapi-schema/enum-dict-member.out b/tests/qapi-schema/enum-dict-member.out
>> deleted file mode 100644
>> index e69de29bb2..0000000000
>
> Hmm. The dict instance of "enum value must be of an appropriate JSON
> type" error class goes away in this patch, but the class remains. Do we
> still cover it?
>
> There's enum-int-member.json, but it's not a good test: it dies in the
> lexer. I think we should replace the two tests by a single one.
> Perhaps something like 'data': [ [] ] would do.
I replaced enum-dict-member by enum-bad-member. I left the int-member
test, because it has also the purpose to check the lexer.
>
>> diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
>> index dc2c444fc1..ad2b405d83 100644
>> --- a/tests/qapi-schema/qapi-schema-test.json
>> +++ b/tests/qapi-schema/qapi-schema-test.json
>> @@ -194,7 +194,8 @@
>> { 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
>> 'if': 'defined(TEST_IF_STRUCT)' }
>>
>> -{ 'enum': 'TestIfEnum', 'data': [ 'foo', 'bar' ],
>> +{ 'enum': 'TestIfEnum', 'data':
>> + [ 'foo', { 'name' : 'bar', 'if': 'defined(TEST_IF_ENUM_BAR)' } ],
>> 'if': 'defined(TEST_IF_ENUM)' }
>>
>> { 'union': 'TestIfUnion', 'data': { 'foo': 'TestStruct' },
>> @@ -203,7 +204,7 @@
>> { 'alternate': 'TestIfAlternate', 'data': { 'foo': 'int', 'bar': 'TestStruct' },
>> 'if': 'defined(TEST_IF_ALT) && defined(TEST_IF_STRUCT)' }
>>
>> -{ 'command': 'TestIfCmd', 'data': { 'foo': 'TestIfStruct' },
>> +{ 'command': 'TestIfCmd', 'data': { 'foo': 'TestIfStruct', 'bar': 'TestIfEnum' },
>> 'if': 'defined(TEST_IF_CMD) && defined(TEST_IF_STRUCT)' }
>>
>> { 'event': 'TestIfEvent', 'data': { 'foo': 'TestIfStruct' },
>
> Should this hunk be in PATCH 04?
It could, but it is not necessary until conditionals are added to
verify introspection generation.
>
>> diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
>> index 9a7cafc269..8a0cf1a551 100644
>> --- a/tests/qapi-schema/qapi-schema-test.out
>> +++ b/tests/qapi-schema/qapi-schema-test.out
>> @@ -74,7 +74,7 @@ command TestIfCmd q_obj_TestIfCmd-arg -> None
>> if defined(TEST_IF_CMD) && defined(TEST_IF_STRUCT)
>> enum TestIfEnum
>> member foo:
>> - member bar:
>> + member bar: if=defined(TEST_IF_ENUM_BAR)
>> if defined(TEST_IF_ENUM)
>> event TestIfEvent q_obj_TestIfEvent-arg
>> boxed=False
>> @@ -228,6 +228,7 @@ object q_obj_EVENT_D-arg
>> member enum3: EnumOne optional=True
>> object q_obj_TestIfCmd-arg
>> member foo: TestIfStruct optional=False
>> + member bar: TestIfEnum optional=False
>> if defined(TEST_IF_CMD) && defined(TEST_IF_STRUCT)
>> object q_obj_TestIfEvent-arg
>> member foo: TestIfStruct optional=False
>> diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
>> index 67c6c1ecef..a86c3b5ee1 100644
>> --- a/tests/qapi-schema/test-qapi.py
>> +++ b/tests/qapi-schema/test-qapi.py
>> @@ -56,6 +56,8 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
>> print ' member %s:' % m.name,
>> if isinstance(m, QAPISchemaObjectTypeMember):
>> print '%s optional=%s' % (m.type.name, m.optional),
>> + if m.ifcond:
>> + print 'if=%s' % m.ifcond,
>> print
>>
>> @staticmethod
>
--
Marc-André Lureau
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 20/50] qapi-event: add 'if' condition to generated enum
2017-12-08 14:07 ` Markus Armbruster
@ 2018-01-11 21:31 ` Marc-André Lureau
0 siblings, 0 replies; 118+ messages in thread
From: Marc-André Lureau @ 2018-01-11 21:31 UTC (permalink / raw)
To: Markus Armbruster; +Cc: QEMU, Michael Roth
Hi
On Fri, Dec 8, 2017 at 3:07 PM, Markus Armbruster <armbru@redhat.com> wrote:
> Markus Armbruster <armbru@redhat.com> writes:
>
>> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>>
>>> Add condition to QAPIEvent enum members based on the event 'if'.
>>>
>>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>>> ---
>>> scripts/qapi-event.py | 2 +-
>>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py
>>> index 38f4264817..60c6f7030d 100644
>>> --- a/scripts/qapi-event.py
>>> +++ b/scripts/qapi-event.py
>>> @@ -168,7 +168,7 @@ class QAPISchemaGenEventVisitor(QAPISchemaVisitor):
>>> def visit_event(self, name, info, ifcond, arg_type, boxed):
>>> self.decl += gen_event_send_decl(name, arg_type, boxed)
>>> self.defn += gen_event_send(name, arg_type, boxed)
>>> - self._event_names.append(QAPISchemaMember(name))
>>> + self._event_names.append(QAPISchemaMember(name, ifcond))
>>>
>>>
>>> (input_file, output_dir, do_c, do_h, prefix, dummy) = parse_command_line()
>>
>> No test coverage?
There is no coverage of this change in qapi-schema-test.out since the
event_names enum is an implicit type created by qapi-event.py.
We verify the generated event.h still compiles ;)
Seriously, if necessary we could add a specific test somehow, checking
the generated code further.
>
> Wait! This patch has no effect, because the it merely puts the ifcond
> argument into QAPISchemaMember.ifcond. Only later patches put
> QAPISchemaMember.ifcond to use. Correct?
In general, the patches were splitted this way:
1. accept 'if' in json & verify with visitors
2. add the #if wrapping in the generated code
3. add negative / error tests
In v4, I merged most tests with 1.
> Aside: the ifcond_decorator could already be doing something with the
> argument, but I'll be hanged if I remember how that magic works.
>
It's wrapping visitor methods with a ifcond argument in the previous
patches, not used later.
thanks
--
Marc-André Lureau
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 24/50] qapi: add some struct member tests
2017-12-09 9:07 ` Markus Armbruster
@ 2018-01-11 21:31 ` Marc-André Lureau
2018-02-02 14:51 ` Markus Armbruster
0 siblings, 1 reply; 118+ messages in thread
From: Marc-André Lureau @ 2018-01-11 21:31 UTC (permalink / raw)
To: Markus Armbruster; +Cc: QEMU, Michael Roth
Hi
On Sat, Dec 9, 2017 at 10:07 AM, Markus Armbruster <armbru@redhat.com> wrote:
> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>
>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>> ---
>> tests/Makefile.include | 2 ++
>> tests/qapi-schema/struct-if-invalid.err | 1 +
>> tests/qapi-schema/struct-if-invalid.exit | 1 +
>> tests/qapi-schema/struct-if-invalid.json | 3 +++
>> tests/qapi-schema/struct-if-invalid.out | 0
>> tests/qapi-schema/struct-member-type.err | 0
>> tests/qapi-schema/struct-member-type.exit | 1 +
>> tests/qapi-schema/struct-member-type.json | 2 ++
>> tests/qapi-schema/struct-member-type.out | 12 ++++++++++++
>> 9 files changed, 22 insertions(+)
>> create mode 100644 tests/qapi-schema/struct-if-invalid.err
>> create mode 100644 tests/qapi-schema/struct-if-invalid.exit
>> create mode 100644 tests/qapi-schema/struct-if-invalid.json
>> create mode 100644 tests/qapi-schema/struct-if-invalid.out
>> create mode 100644 tests/qapi-schema/struct-member-type.err
>> create mode 100644 tests/qapi-schema/struct-member-type.exit
>> create mode 100644 tests/qapi-schema/struct-member-type.json
>> create mode 100644 tests/qapi-schema/struct-member-type.out
>>
>> diff --git a/tests/Makefile.include b/tests/Makefile.include
>> index 0aa532f029..44a3d8895e 100644
>> --- a/tests/Makefile.include
>> +++ b/tests/Makefile.include
>> @@ -520,7 +520,9 @@ qapi-schema += returns-whitelist.json
>> qapi-schema += struct-base-clash-deep.json
>> qapi-schema += struct-base-clash.json
>> qapi-schema += struct-data-invalid.json
>> +qapi-schema += struct-if-invalid.json
>> qapi-schema += struct-member-invalid.json
>> +qapi-schema += struct-member-type.json
>> qapi-schema += trailing-comma-list.json
>> qapi-schema += trailing-comma-object.json
>> qapi-schema += type-bypass-bad-gen.json
>> diff --git a/tests/qapi-schema/struct-if-invalid.err b/tests/qapi-schema/struct-if-invalid.err
>> new file mode 100644
>> index 0000000000..42245262a9
>> --- /dev/null
>> +++ b/tests/qapi-schema/struct-if-invalid.err
>> @@ -0,0 +1 @@
>> +tests/qapi-schema/struct-if-invalid.json:2: Member 'bar' of 'data' for struct 'TestIfStruct' should be a type name
>> diff --git a/tests/qapi-schema/struct-if-invalid.exit b/tests/qapi-schema/struct-if-invalid.exit
>> new file mode 100644
>> index 0000000000..d00491fd7e
>> --- /dev/null
>> +++ b/tests/qapi-schema/struct-if-invalid.exit
>> @@ -0,0 +1 @@
>> +1
>> diff --git a/tests/qapi-schema/struct-if-invalid.json b/tests/qapi-schema/struct-if-invalid.json
>> new file mode 100644
>> index 0000000000..466cdb61e1
>> --- /dev/null
>> +++ b/tests/qapi-schema/struct-if-invalid.json
>> @@ -0,0 +1,3 @@
>> +# check missing 'type'
>> +{ 'struct': 'TestIfStruct', 'data':
>> + { 'foo': 'int', 'bar': { 'if': 'defined(TEST_IF_STRUCT_BAR)' } } }
>
> Hmm. This tests the previous patch's change to check_type(). It
> demonstrates that the "should be a type name" error message can be
> suboptimal: it gets triggered when
>
> not isinstance(value, str)
> and not (isinstance(value, dict) and 'type' in value)
>
> Fine when the value is neither str not dict. Suboptimal when it's dict
> and 'type' is missing. A more obvious example of suboptimality would be
>
> 'bar': { 'tvpe': 'int' }
>
> The previous patch's
>
> if isinstance(value, dict) and 'type' in value:
> check_type(info, source, value['type'], allow_array,
> allow_dict, allow_optional, allow_metas)
> if 'if' in value:
> check_if(value, info)
> check_unknown_keys(info, value, {'type', 'if'})
> return
> else:
> raise QAPISemError(info, "%s should be a type name" % source)
>
> should be improved to something like
>
> if not isinstance(value, dict):
> raise QAPISemError(
> info, "%s should be a type name or dictionary" % source)
> if 'type' not in value:
> raise QAPISemError(
> info, "%s must have a member 'type'" % source)
> check_type(info, source, value['type'], allow_array,
> allow_dict, allow_optional, allow_metas)
> if 'if' in value:
> check_if(value, info)
> check_unknown_keys(info, value, {'type', 'if'})
> return
>
> producing
>
> struct-if-invalid.json:2: Member 'bar' of 'data' for struct 'TestIfStruct' must have a member 'type'
>
Fixed differently in v4
> The fact that I missed this in review of the code, but noticed it in the
> tests is why I want tests added together with the code they test.
>
Changed in v4
> Nitpick: the file name struct-if-invalid makes me expect an invalid if.
> Not the case. It's a missing type. Let's rename accordingly.
Done
>
>> diff --git a/tests/qapi-schema/struct-if-invalid.out b/tests/qapi-schema/struct-if-invalid.out
>> new file mode 100644
>> index 0000000000..e69de29bb2
>> diff --git a/tests/qapi-schema/struct-member-type.err b/tests/qapi-schema/struct-member-type.err
>> new file mode 100644
>> index 0000000000..e69de29bb2
>> diff --git a/tests/qapi-schema/struct-member-type.exit b/tests/qapi-schema/struct-member-type.exit
>> new file mode 100644
>> index 0000000000..573541ac97
>> --- /dev/null
>> +++ b/tests/qapi-schema/struct-member-type.exit
>> @@ -0,0 +1 @@
>> +0
>> diff --git a/tests/qapi-schema/struct-member-type.json b/tests/qapi-schema/struct-member-type.json
>> new file mode 100644
>> index 0000000000..8b33027817
>> --- /dev/null
>> +++ b/tests/qapi-schema/struct-member-type.json
>> @@ -0,0 +1,2 @@
>> +# check member 'a' with 'type' key only
>> +{ 'struct': 'foo', 'data': { 'a': { 'type': 'str' } } }
>> diff --git a/tests/qapi-schema/struct-member-type.out b/tests/qapi-schema/struct-member-type.out
>> new file mode 100644
>> index 0000000000..04b969d2e3
>> --- /dev/null
>> +++ b/tests/qapi-schema/struct-member-type.out
>> @@ -0,0 +1,12 @@
>> +enum QType
>> + prefix QTYPE
>> + member none:
>> + member qnull:
>> + member qnum:
>> + member qstring:
>> + member qdict:
>> + member qlist:
>> + member qbool:
>> +object foo
>> + member a: str optional=False
>> +object q_empty
>
> This is a positive test, isn't it? Positive tests go into
> qapi-schema-test.json.
>
Right, I wonder why we have .exit files then. Perhaps the few ones
that return 0 shouldn't exist.
thanks
--
Marc-André Lureau
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 26/50] qapi: add 'if' on union variants
2017-12-11 10:36 ` Markus Armbruster
@ 2018-01-11 21:32 ` Marc-André Lureau
0 siblings, 0 replies; 118+ messages in thread
From: Marc-André Lureau @ 2018-01-11 21:32 UTC (permalink / raw)
To: Markus Armbruster; +Cc: QEMU, Michael Roth
Hi
On Mon, Dec 11, 2017 at 11:36 AM, Markus Armbruster <armbru@redhat.com> wrote:
> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>
>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>> ---
>> scripts/qapi.py | 15 ++++++++++-----
>> tests/qapi-schema/qapi-schema-test.json | 7 ++++++-
>> tests/qapi-schema/qapi-schema-test.out | 8 ++++++++
>> tests/qapi-schema/test-qapi.py | 5 ++++-
>> 4 files changed, 28 insertions(+), 7 deletions(-)
>>
>> diff --git a/scripts/qapi.py b/scripts/qapi.py
>> index 15711f96fa..2f14edfa1f 100644
>> --- a/scripts/qapi.py
>> +++ b/scripts/qapi.py
>> @@ -1412,8 +1412,8 @@ class QAPISchemaObjectTypeVariants(object):
>> class QAPISchemaObjectTypeVariant(QAPISchemaObjectTypeMember):
>> role = 'branch'
>>
>> - def __init__(self, name, typ):
>> - QAPISchemaObjectTypeMember.__init__(self, name, typ, False)
>> + def __init__(self, name, typ, ifcond=None):
>> + QAPISchemaObjectTypeMember.__init__(self, name, typ, False, ifcond)
>>
>>
>> class QAPISchemaAlternateType(QAPISchemaType):
>> @@ -1674,13 +1674,18 @@ class QAPISchema(object):
>> return QAPISchemaObjectTypeVariant(case, typ)
>>
>> def _make_simple_variant(self, case, typ, info):
>> + ifcond = None
>> + if isinstance(typ, dict):
>> + check_unknown_keys(info, typ, {'type', 'if'})
>> + ifcond = typ.get('if')
>> + typ = typ['type']
>> if isinstance(typ, list):
>> assert len(typ) == 1
>> typ = self._make_array_type(typ[0], info)
>> typ = self._make_implicit_object_type(
>> typ, info, None, self.lookup_type(typ).ifcond,
>> 'wrapper', [self._make_member('data', typ, info)])
>> - return QAPISchemaObjectTypeVariant(case, typ)
>> + return QAPISchemaObjectTypeVariant(case, typ, ifcond)
>>
>> def _def_union_type(self, expr, info, doc):
>> name = expr['union']
>> @@ -1700,8 +1705,8 @@ class QAPISchema(object):
>> else:
>> variants = [self._make_simple_variant(key, value, info)
>> for (key, value) in data.iteritems()]
>> - typ = self._make_implicit_enum_type(name, info, ifcond,
>> - [v.name for v in variants])
>> + values = [{'name': v.name, 'if': v.ifcond} for v in variants]
>> + typ = self._make_implicit_enum_type(name, info, ifcond, values)
>> tag_member = QAPISchemaObjectTypeMember('type', typ, False)
>> members = [tag_member]
>> self._def_entity(
>> diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
>> index 5cfccabb3d..895e80a978 100644
>> --- a/tests/qapi-schema/qapi-schema-test.json
>> +++ b/tests/qapi-schema/qapi-schema-test.json
>> @@ -200,9 +200,14 @@
>> [ 'foo', { 'name' : 'bar', 'if': 'defined(TEST_IF_ENUM_BAR)' } ],
>> 'if': 'defined(TEST_IF_ENUM)' }
>>
>> -{ 'union': 'TestIfUnion', 'data': { 'foo': 'TestStruct' },
>> +{ 'union': 'TestIfUnion', 'data':
>> + { 'foo': 'TestStruct',
>> + 'union_bar': { 'type': 'str', 'if': 'defined(TEST_IF_UNION_BAR)'} },
>> 'if': 'defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)' }
>>
>> +{ 'command': 'TestIfUnionCmd', 'data': { 'union_cmd_arg': 'TestIfUnion' },
>> + 'if': 'defined(TEST_IF_UNION)' }
>> +
>> { 'alternate': 'TestIfAlternate', 'data': { 'foo': 'int', 'bar': 'TestStruct' },
>> 'if': 'defined(TEST_IF_ALT) && defined(TEST_IF_STRUCT)' }
>>
>> diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
>> index 6df4e49c69..ee009c5626 100644
>> --- a/tests/qapi-schema/qapi-schema-test.out
>> +++ b/tests/qapi-schema/qapi-schema-test.out
>> @@ -87,9 +87,14 @@ object TestIfUnion
>> member type: TestIfUnionKind optional=False
>> tag type
>> case foo: q_obj_TestStruct-wrapper
>> + case union_bar: q_obj_str-wrapper if=defined(TEST_IF_UNION_BAR)
>
> PATCH 22, but I only spotted it here. We say "if=COND" in some places,
> ...
>
>> if defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)
>> +command TestIfUnionCmd q_obj_TestIfUnionCmd-arg -> None
>> + gen=True success_response=True boxed=False
>> + if defined(TEST_IF_UNION)
>
> ... and "if COND" in other places. I guess the '=' is there to match
> existing flag printing like optional=BOOL.
>
> I'd prefer less decorated output, i.e. instead of
>
> enum TestIfEnum
> member foo:
> member bar: if=defined(TEST_IF_ENUM_BAR)
> if defined(TEST_IF_ENUM)
>
> something like
>
> enum TestIfEnum
> member foo
> member bar
> if defined(TEST_IF_ENUM_BAR)
> if defined(TEST_IF_ENUM)
>
> Could touch that up on commit.
>
ok, changed
>> enum TestIfUnionKind
>> member foo:
>> + member union_bar: if=defined(TEST_IF_UNION_BAR)
>> if defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)
>> object TestStruct
>> member integer: int optional=False
>> @@ -235,6 +240,9 @@ object q_obj_TestIfEvent-arg
>> member foo: TestIfStruct optional=False
>> member bar: TestIfEnum optional=False if=defined(TEST_IF_EVT_BAR)
>> if defined(TEST_IF_EVT) && defined(TEST_IF_STRUCT)
>> +object q_obj_TestIfUnionCmd-arg
>> + member union_cmd_arg: TestIfUnion optional=False
>> + if defined(TEST_IF_UNION)
>> object q_obj_TestStruct-wrapper
>> member data: TestStruct optional=False
>> object q_obj_UserDefFlatUnion2-base
>> diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
>> index a86c3b5ee1..87a8efff78 100644
>> --- a/tests/qapi-schema/test-qapi.py
>> +++ b/tests/qapi-schema/test-qapi.py
>> @@ -65,7 +65,10 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
>> if variants:
>> print ' tag %s' % variants.tag_member.name
>> for v in variants.variants:
>> - print ' case %s: %s' % (v.name, v.type.name)
>> + print ' case %s: %s' % (v.name, v.type.name),
>> + if v.ifcond:
>> + print 'if=%s' % v.ifcond,
>> + print
>>
>> @staticmethod
>> def _print_if(ifcond):
>
--
Marc-André Lureau
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 43/50] build-sys: move qmp-introspect per target
2017-12-14 16:30 ` Markus Armbruster
@ 2018-01-11 21:32 ` Marc-André Lureau
0 siblings, 0 replies; 118+ messages in thread
From: Marc-André Lureau @ 2018-01-11 21:32 UTC (permalink / raw)
To: Markus Armbruster; +Cc: QEMU, Michael Roth
Hi
On Thu, Dec 14, 2017 at 5:30 PM, Markus Armbruster <armbru@redhat.com> wrote:
> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>
>> The following patches are going to introduce per-target #ifdef, and
>> but the introspection data is generated only once, and must thus be
>> built with the target.
>
> "and but"?
>
>> Drop "do_test_visitor_in_qmp_introspect(&&qmp_schema_qlit)" since it
>
> s/&&/&/
>
>> is no longer in a common object, and covered by "query-qmp-schema
>> test" instead.
>
> Do you mean test /x86_64/qmp/query-qmp-schema of tests/qmp-test.c?
>
I updated the commit message.
> That test tests significantly less. It runs the command, tests it
> succeeds and returns something. The test you remove additionally tests
> the returned value conforms to the schema, by passing it to
> visit_type_SchemaInfoList().
>
> Perhaps we can enhance the test you keep to avoid this loss.
>
It does call visit_type_SchemaInfoList() already on the return value.
thanks
--
Marc-André Lureau
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 44/50] build-sys: add a target schema
2017-12-14 16:34 ` Markus Armbruster
@ 2018-01-11 21:32 ` Marc-André Lureau
0 siblings, 0 replies; 118+ messages in thread
From: Marc-André Lureau @ 2018-01-11 21:32 UTC (permalink / raw)
To: Markus Armbruster; +Cc: QEMU, Dr. David Alan Gilbert
Hi
On Thu, Dec 14, 2017 at 5:34 PM, Markus Armbruster <armbru@redhat.com> wrote:
> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>
>> This schema is going to contain target-specific commands/events &
>> types, that can be conditionnally guarded with poisoned defines. To
>> filter it out by default, set the unit name to 'target'.
>>
>> And new rules to compile this unit generated files per-target.
>>
>> Use the "-u all" options for the introspection schema, since it is
>> generated as a single file and must contain all definitions.
>>
>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>> ---
>> qapi-schema.json | 1 +
>> qapi/target.json | 3 +++
>> monitor.c | 2 ++
>> Makefile | 29 ++++++++++++++++++++++++++++-
>> Makefile.target | 2 ++
>> 5 files changed, 36 insertions(+), 1 deletion(-)
>> create mode 100644 qapi/target.json
>>
>> diff --git a/qapi-schema.json b/qapi-schema.json
>> index f3af2cb851..42b6aebddb 100644
>> --- a/qapi-schema.json
>> +++ b/qapi-schema.json
>> @@ -92,6 +92,7 @@
>> { 'include': 'qapi/transaction.json' }
>> { 'include': 'qapi/trace.json' }
>> { 'include': 'qapi/introspect.json' }
>> +{ 'include': 'qapi/target.json' }
>>
>> ##
>> # = Miscellanea
>> diff --git a/qapi/target.json b/qapi/target.json
>> new file mode 100644
>> index 0000000000..e9644f52c2
>> --- /dev/null
>> +++ b/qapi/target.json
>> @@ -0,0 +1,3 @@
>> +# -*- Mode: Python -*-
>> +
>> +{ 'pragma': { 'unit': 'target' } }
>> diff --git a/monitor.c b/monitor.c
>> index bf8a7685bf..af4eaeca5e 100644
>> --- a/monitor.c
>> +++ b/monitor.c
>> @@ -68,6 +68,7 @@
>> #include "exec/exec-all.h"
>> #include "qemu/log.h"
>> #include "qmp-commands.h"
>> +#include "target-qmp-commands.h"
>> #include "hmp.h"
>> #include "qemu/thread.h"
>> #include "block/qapi.h"
>> @@ -1003,6 +1004,7 @@ void monitor_init_qmp_commands(void)
>>
>> QTAILQ_INIT(&qmp_commands);
>> qmp_init_marshal(&qmp_commands);
>> + target_qmp_init_marshal(&qmp_commands);
>>
>> qmp_register_command(&qmp_commands, "query-qmp-schema",
>> qmp_query_qmp_schema,
>> diff --git a/Makefile b/Makefile
>> index 337a1f6f9b..7356b4e7b7 100644
>> --- a/Makefile
>> +++ b/Makefile
>> @@ -54,6 +54,8 @@ include $(SRC_PATH)/rules.mak
>> GENERATED_FILES = qemu-version.h config-host.h qemu-options.def
>> GENERATED_FILES += qmp-commands.h qapi-types.h qapi-visit.h qapi-event.h
>> GENERATED_FILES += qmp-marshal.c qapi-types.c qapi-visit.c qapi-event.c
>> +GENERATED_FILES += target-qmp-commands.h target-qapi-types.h target-qapi-visit.h target-qapi-event.h
>> +GENERATED_FILES += target-qmp-marshal.c target-qapi-types.c target-qapi-visit.c target-qapi-event.c
>> GENERATED_FILES += qmp-introspect.h
>> GENERATED_FILES += qmp-introspect.c
>>
>> @@ -418,6 +420,7 @@ qapi-modules = $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi/common.json \
>> $(SRC_PATH)/qapi/rocker.json \
>> $(SRC_PATH)/qapi/run-state.json \
>> $(SRC_PATH)/qapi/sockets.json \
>> + $(SRC_PATH)/qapi/target.json \
>> $(SRC_PATH)/qapi/tpm.json \
>> $(SRC_PATH)/qapi/trace.json \
>> $(SRC_PATH)/qapi/transaction.json \
>> @@ -443,10 +446,34 @@ $(qapi-modules) $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
>> $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py \
>> $(gen-out-type) -o "." $<, \
>> "GEN","$@")
>> +
>> +target-qapi-types.c target-qapi-types.h :\
>> +$(qapi-modules) $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
>> + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py \
>> + -i qapi-types.h \
>> + $(gen-out-type) -p target- -u target $<, \
>> + "GEN","$@")
>> +target-qapi-visit.c target-qapi-visit.h :\
>> +$(qapi-modules) $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py)
>> + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py \
>> + -i qapi-visit.h \
>> + $(gen-out-type) -p target- -u target $<, \
>> + "GEN","$@")
>> +target-qapi-event.c target-qapi-event.h :\
>> +$(qapi-modules) $(SRC_PATH)/scripts/qapi-event.py $(qapi-py)
>> + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-event.py \
>> + $(gen-out-type) -p target- -u target $<, \
>> + "GEN","$@")
>> +target-qmp-commands.h target-qmp-marshal.c :\
>> +$(qapi-modules) $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
>> + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py \
>> + $(gen-out-type) -p target- -u target $<, \
>> + "GEN","$@")
>> +
>> qmp-introspect.h qmp-introspect.c :\
>> $(qapi-modules) $(SRC_PATH)/scripts/qapi-introspect.py $(qapi-py)
>> $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-introspect.py \
>> - $(gen-out-type) -o "." $<, \
>> + $(gen-out-type) -o "." -u all $<, \
>> "GEN","$@")
>>
>
> Let's see whether I understand how this works. Without -u (not fully
> visible in the diff), we get everything but the target-specific stuff.
> With -u target, we get just the target-specific stuff. With -u all, we
> get everything. Correct?
>
Right, but I changed the logic as discussed in "qapi: add a -u/--unit
option to specify which unit to visit " (this changes a bit the way
inclusion is being done, now target.json is the top-level for the
documentation)
So only -u target will be needed to generate the target specific code
now (while still parsing and checking with the rest of the schemas)
All documentation is generated from target.json. The rest is
unaffected by this new schema (which is a good thing imho).
>> QGALIB_GEN=$(addprefix qga/qapi-generated/, qga-qapi-types.h qga-qapi-visit.h qga-qmp-commands.h)
>> diff --git a/Makefile.target b/Makefile.target
>> index 0d28ed1df0..e44a3847d3 100644
>> --- a/Makefile.target
>> +++ b/Makefile.target
>> @@ -157,6 +157,8 @@ endif
>>
>> GENERATED_FILES += hmp-commands.h hmp-commands-info.h
>>
>> +obj-y += target-qapi-types.o target-qapi-visit.o
>> +obj-y += target-qapi-event.o target-qmp-marshal.o
>> obj-y += qmp-introspect.o
>>
>> endif # CONFIG_SOFTMMU
>
thanks
--
Marc-André Lureau
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 17/50] qapi: do not define enumeration value explicitely
2018-01-11 21:24 ` Marc-André Lureau
@ 2018-02-02 14:43 ` Markus Armbruster
0 siblings, 0 replies; 118+ messages in thread
From: Markus Armbruster @ 2018-02-02 14:43 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: QEMU, Michael Roth
Marc-André Lureau <marcandre.lureau@gmail.com> writes:
> Hi
>
> On Fri, Dec 8, 2017 at 8:50 AM, Markus Armbruster <armbru@redhat.com> wrote:
>> Marc-André Lureau <marcandre.lureau@gmail.com> writes:
>>
>>> On Thu, Dec 7, 2017 at 5:23 PM, Markus Armbruster <armbru@redhat.com> wrote:
>>>> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>>>>
>>>>> The C standard has the initial value at 0 and the subsequent values
>>>>> incremented by 1. No need to set this explicitely.
>>>>>
>>>>> This will prevent from artificial "gaps" when compiling out some enum
>>>>> values and having unnecessarily large MAX values & enums arrays.
>>>>>
>>>>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>>>>> ---
>>>>> scripts/qapi.py | 7 ++-----
>>>>> 1 file changed, 2 insertions(+), 5 deletions(-)
>>>>>
>>>>> diff --git a/scripts/qapi.py b/scripts/qapi.py
>>>>> index 94b735d8d6..074ee221a1 100644
>>>>> --- a/scripts/qapi.py
>>>>> +++ b/scripts/qapi.py
>>>>> @@ -1985,14 +1985,11 @@ typedef enum %(c_name)s {
>>>>> ''',
>>>>> c_name=c_name(name))
>>>>>
>>>>> - i = 0
>>>>> for value in enum_values:
>>>>> ret += mcgen('''
>>>>> - %(c_enum)s = %(i)d,
>>>>> + %(c_enum)s,
>>>>> ''',
>>>>> - c_enum=c_enum_const(name, value, prefix),
>>>>> - i=i)
>>>>> - i += 1
>>>>> + c_enum=c_enum_const(name, value, prefix))
>>>>>
>>>>> ret += mcgen('''
>>>>> } %(c_name)s;
>>>>
>>>> Recapitulate review of v2: this risks entertaining mishaps like
>>>> compiling this one
>>>>
>>>> typedef enum Color {
>>>> COLOR_WHITE,
>>>> #if defined(NEED_CPU_H)
>>>> #if defined(TARGET_S390X)
>>>> COLOR_BLUE,
>>>> #endif /* defined(TARGET_S390X) */
>>>> #endif /* defined(NEED_CPU_H) */
>>>> COLOR_BLACK,
>>>> } Color;
>>>>
>>>> in s390x-code (COLOR_BLACK = 2) and in target-independent code
>>>> (COLOR_BLACK = 1), then linking the two together.
>>>>
>>>> Same issue for struct members and such (previous patch).
>>>>
>>>> What's our story on preventing disaster here?
>>>>
>>>> In the long run, we want to split the generated code so that
>>>> target-specific and target-independent code are separate, and each part
>>>> is always compiled with consistent preprocessor symbols. But I'm afraid
>>>> that's not in the card right now.
>>>
>>> Eh, I need to refresh my memories about that series, but I think
>>> that's what I did in v3
>>>
>>> It doesn't use the NEED_CPU_H trick. It has a seperate per-target target.json
>>
>> Looking... aha! target.json appears in PATCH 44 (which I haven't even
>> glanced at, yet). The problem appears in PATCH 16, though. Perhaps a
>> bit of patch reshuffling would do.
>
> What problem appears in patch 16? Some code could be introduced using
> NEED_CPU_H and link arch & independent code together?
It's been a while...
Generated headers using conditionals must include the headers providing
the symbols used in conditionals. Not doing so is an open death trap.
PATCH 16 sets up the first instance of the death trap. Or maybe it's
PATCH 13.
However, including these headers only becomes possible *after* you split
off the target-specific stuff in PATCH 44.
Do I make any sense?
> It is still true
> after patch 44. If necessary, I can work on a split-qapi series before
> the conditionals are added. But the real benefit is only apparent
> after the conditional are introduced, so I am not motivated to
> reorder.
Understand.
As a maintainer, I can ask for improvements, but the only lever I have
is saying no. Which should be reserved for cases that are actually
wrong, or create inacceptable technical debt. Temporary death traps
don't count as either. For cases I merely hate, when asking doesn't
help, all I can do is do the work myself. So I did:
[PATCH RFC 00/21] Modularize generated QAPI code
Message-Id: <20180202130336.24719-1-armbru@redhat.com>
[...]
^ permalink raw reply [flat|nested] 118+ messages in thread
* Re: [Qemu-devel] [PATCH v3 24/50] qapi: add some struct member tests
2018-01-11 21:31 ` Marc-André Lureau
@ 2018-02-02 14:51 ` Markus Armbruster
0 siblings, 0 replies; 118+ messages in thread
From: Markus Armbruster @ 2018-02-02 14:51 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: QEMU, Michael Roth
Marc-André Lureau <marcandre.lureau@gmail.com> writes:
> Hi
>
> On Sat, Dec 9, 2017 at 10:07 AM, Markus Armbruster <armbru@redhat.com> wrote:
>> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
[...]
>>> diff --git a/tests/qapi-schema/struct-member-type.json b/tests/qapi-schema/struct-member-type.json
>>> new file mode 100644
>>> index 0000000000..8b33027817
>>> --- /dev/null
>>> +++ b/tests/qapi-schema/struct-member-type.json
>>> @@ -0,0 +1,2 @@
>>> +# check member 'a' with 'type' key only
>>> +{ 'struct': 'foo', 'data': { 'a': { 'type': 'str' } } }
>>> diff --git a/tests/qapi-schema/struct-member-type.out b/tests/qapi-schema/struct-member-type.out
>>> new file mode 100644
>>> index 0000000000..04b969d2e3
>>> --- /dev/null
>>> +++ b/tests/qapi-schema/struct-member-type.out
>>> @@ -0,0 +1,12 @@
>>> +enum QType
>>> + prefix QTYPE
>>> + member none:
>>> + member qnull:
>>> + member qnum:
>>> + member qstring:
>>> + member qdict:
>>> + member qlist:
>>> + member qbool:
>>> +object foo
>>> + member a: str optional=False
>>> +object q_empty
>>
>> This is a positive test, isn't it? Positive tests go into
>> qapi-schema-test.json.
>>
>
> Right, I wonder why we have .exit files then. Perhaps the few ones
> that return 0 shouldn't exist.
There are a few legitimate positive test cases, such as empty.json and
doc-good.json.
Moreover, we occasionally add negative test cases that fail to fail,
demonstrating a bug. Example: quoted-structural-chars in commit
98626572f1, fixed in commit c7a3f25200.
^ permalink raw reply [flat|nested] 118+ messages in thread
end of thread, other threads:[~2018-02-02 14:51 UTC | newest]
Thread overview: 118+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 01/50] qlit: add qobject_from_qlit() Marc-André Lureau
2017-09-13 13:51 ` Eric Blake
2017-09-13 14:08 ` Marc-André Lureau
2017-12-06 14:37 ` Markus Armbruster
2017-12-06 14:37 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 02/50] qapi: generate a literal qobject for introspection Marc-André Lureau
2017-12-06 15:17 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 03/50] qapi2texi: minor python code simplification Marc-André Lureau
2017-12-06 15:19 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 04/50] qapi: add 'if' to top-level expressions Marc-André Lureau
2017-12-06 15:46 ` Markus Armbruster
2017-12-06 16:23 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 05/50] qapi: add tests for invalid 'if' Marc-André Lureau
2017-12-06 16:34 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 06/50] qapi: pass 'if' condition into QAPISchemaEntity objects Marc-André Lureau
2017-12-06 17:13 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 07/50] qapi: add 'ifcond' to visitor methods Marc-André Lureau
2017-12-06 17:23 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 08/50] qapi: mcgen() shouldn't indent # lines Marc-André Lureau
2017-12-06 17:41 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 09/50] qapi: add #if/#endif helpers Marc-André Lureau
2017-12-07 14:10 ` Markus Armbruster
2018-01-11 21:21 ` Marc-André Lureau
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 10/50] qapi-introspect: modify to_qlit() to append ', ' on level > 0 Marc-André Lureau
2017-12-07 14:47 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 11/50] qapi-introspect: modify to_qlit() to generate #if code Marc-André Lureau
2017-12-07 14:50 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 12/50] qapi-introspect: add preprocessor conditions to generated QLit Marc-André Lureau
2017-12-07 15:41 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 13/50] qapi-commands: add #if conditions to commands Marc-André Lureau
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 14/50] qapi-event: add #if conditions to events Marc-André Lureau
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 15/50] qapi-types: refactor variants handling Marc-André Lureau
2017-12-07 15:57 ` Markus Armbruster
2018-01-11 21:22 ` Marc-André Lureau
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 16/50] qapi-types: add #if conditions to types & visitors Marc-André Lureau
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 17/50] qapi: do not define enumeration value explicitely Marc-André Lureau
2017-12-07 16:23 ` Markus Armbruster
2017-12-07 17:01 ` Marc-André Lureau
2017-12-08 7:50 ` Markus Armbruster
2018-01-11 21:24 ` Marc-André Lureau
2018-02-02 14:43 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 18/50] qapi: change enum visitor to take QAPISchemaMember Marc-André Lureau
2017-12-07 17:34 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 19/50] qapi: add 'if' to enum members Marc-André Lureau
2017-12-08 8:38 ` Markus Armbruster
2018-01-11 21:24 ` Marc-André Lureau
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 20/50] qapi-event: add 'if' condition to generated enum Marc-André Lureau
2017-12-08 13:58 ` Markus Armbruster
2017-12-08 14:07 ` Markus Armbruster
2018-01-11 21:31 ` Marc-André Lureau
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 21/50] qapi: add #if conditions on generated enum members Marc-André Lureau
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 22/50] tests: add some enum members tests Marc-André Lureau
2017-12-08 17:58 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 23/50] qapi: add 'if' to struct members and implicit objects members Marc-André Lureau
2017-12-09 8:18 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 24/50] qapi: add some struct member tests Marc-André Lureau
2017-12-09 9:07 ` Markus Armbruster
2018-01-11 21:31 ` Marc-André Lureau
2018-02-02 14:51 ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 25/50] qapi: add #if conditions to generated struct members Marc-André Lureau
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 26/50] qapi: add 'if' on union variants Marc-André Lureau
2017-12-11 10:36 ` Markus Armbruster
2018-01-11 21:32 ` Marc-André Lureau
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 27/50] qapi: add #if conditions to generated variants Marc-André Lureau
2017-12-13 12:37 ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 28/50] qapi: add 'if' to alternate variant Marc-André Lureau
2017-12-12 14:51 ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 29/50] qapi: add tests for invalid alternate Marc-André Lureau
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 30/50] qapi: add #if conditions to generated alternate variants Marc-André Lureau
2017-12-12 19:25 ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 31/50] docs: document schema configuration Marc-André Lureau
2017-12-13 10:41 ` Markus Armbruster
2017-12-13 19:49 ` Eric Blake
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 32/50] qapi2texi: add 'If:' section to generated documentation Marc-André Lureau
2017-12-13 12:35 ` Markus Armbruster
2017-12-13 19:54 ` Eric Blake
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 33/50] qapi2texi: add 'If:' condition to enum values Marc-André Lureau
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 34/50] qapi2texi: add 'If:' condition to struct members Marc-André Lureau
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 35/50] qapi2texi: add condition to variants Marc-André Lureau
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 36/50] qapi: add conditions to VNC type/commands/events on the schema Marc-André Lureau
2017-12-13 14:12 ` Markus Armbruster
2017-12-13 14:20 ` Daniel P. Berrange
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 37/50] qapi: add conditions to SPICE " Marc-André Lureau
2017-12-13 14:17 ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 38/50] qapi: add conditions to REPLICATION type/commands " Marc-André Lureau
2017-12-13 14:19 ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 39/50] qapi-commands: don't initialize command list in qmp_init_marshall() Marc-André Lureau
2017-12-13 16:23 ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 40/50] qapi: add -i/--include filename.h Marc-André Lureau
2017-12-14 13:50 ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 41/50] qapi: add a 'unit' pragma Marc-André Lureau
2017-12-14 13:54 ` Markus Armbruster
2017-12-14 14:00 ` Marc-André Lureau
2017-12-14 14:33 ` Markus Armbruster
2017-12-14 16:08 ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 42/50] qapi: add a -u/--unit option to specify which unit to visit Marc-André Lureau
2017-12-14 16:16 ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 43/50] build-sys: move qmp-introspect per target Marc-André Lureau
2017-12-14 16:30 ` Markus Armbruster
2018-01-11 21:32 ` Marc-André Lureau
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 44/50] build-sys: add a target schema Marc-André Lureau
2017-12-14 16:34 ` Markus Armbruster
2018-01-11 21:32 ` Marc-André Lureau
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 45/50] qapi: make rtc-reset-reinjection depend on TARGET_I386 Marc-André Lureau
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 46/50] qapi: make s390 commands depend on TARGET_S390X Marc-André Lureau
2017-09-13 7:45 ` Cornelia Huck
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 47/50] target.json: add a note about query-cpu* not being s390x-specific Marc-André Lureau
2017-09-13 7:46 ` Cornelia Huck
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 48/50] qapi: make query-gic-capabilities depend on TARGET_ARM Marc-André Lureau
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 49/50] qapi: make query-cpu-model-expansion depend on s390 or x86 Marc-André Lureau
2017-09-12 17:40 ` Eduardo Habkost
2017-09-13 7:47 ` Cornelia Huck
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 50/50] qapi: make query-cpu-definitions depend on specific targets Marc-André Lureau
2017-09-12 17:45 ` Eduardo Habkost
2017-09-13 7:48 ` Cornelia Huck
2017-09-11 11:54 ` [Qemu-devel] [PATCH v3 00/50] Hi, no-reply
2017-12-18 13:14 ` Markus Armbruster
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.