* [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code
@ 2018-03-21 11:51 Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 01/49] qapi/visit: remove useless prefix argument Marc-André Lureau
` (53 more replies)
0 siblings, 54 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
Hi,
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 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 demonstrates adding conditions.
The schema is splitted in common and per-target parts starting from
"RFC: qapi: learn to split schema by 'top-unit'" patch. This allows a
target schema to use target-poisoned defines as conditions (such as
TARGET_I386).
There are a lot more things one can 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,
v5:
- adapt to the new 'modular' / single generator design, making
splitting schema a bit more complicated than before, when it was
only at build-sys level. See "RFC: qapi: learn to split schema by
'top-unit'" for the new apporach at splitting common and target
parts.
- replace the #if-wrapper decorator with a @contextmanager (if necessary,
this could be replaced by explicit begin/end calls instead now)
- better split of target events, introducing seperate limiter/emitter
- add a 'RFC: make RTC_CHANGE per-target' to show how conditional
could be used and exercice the 'per-unit' event limiter
- +painful rebase
- add some r-b tags
v4:
- added "qlit: use QType instead of int" patch
- use a "default:" case in qobject_from_qlit()
- added a test for invalid 'if': ['']
- listify ifcond in constructors
- added "qapi: leave the ifcond attribute undefined until check()"
patch (could be squashed)
- use a negative lookahead in "qapi: mcgen() shouldn't indent # lines"
- fix extra empty line in "qapi-introspect: add preprocessor
conditions to generated QLit"
- added desugar/normalization passes, such as NAME -> { 'name': NAME }
- splitted "qapi: change enum visitor to take QAPISchemaMember"
- prettify test-qapi.py members output
- added missing #if wrapping for enum members in generated introspection
- clarified some error messages
- added "qapi: rename allow_dict to allow_implicit" patch for clarity
- added a seperate patch for "qapi: add a dictionnary form" for enum
names
- added a seperate patch for "qapi: add a dictionnary form" for struct
members
- squashed the patches adding #if to generated code (some types
generate both enum and struct members for example, so a step-by-step
is unnecessarily complicated to deal with)
- squashed some tests with related patch
- added "qapi: add an error in case a discriminator is conditionnal"
- add back VNC-specific crypto 'des-rfb' when VNC is disabled
- change the way unit filtering is done (so no -u means no filtering)
- made target.json the top-level documentation schema
- removed some blank lines in generated code output
- improve documentation, add various tests
- commit message improvements
- misc pycodestyle/pep8 fixes
- add r-b tags
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
v2: after Markus review
- "qboject: add literal qobject type", splitted & many updates
- "qapi: generate a literal qobject for introspection", fixed leak
- "visitor: pass size of strings array to enum visitor", rewrote as a
series of patches to change char*[] to struct { int n, char *[] }.
- split the "if" patches in parsing, tests, generation
- added a docs/devel/qapi-code-gen.txt patch
- added a patch to remove enum value assignment, to avoid "holes"
with #if values
- update #if VNC patch, compile out "info vnc", compile out des-rfb
- dropped "qobject: replace dump_qobject() by qobject_to_string()" patch
- dropped qapi.mk patch
- other smaller changes
Marc-André Lureau (49):
qapi/visit: remove useless prefix argument
qapi/events: generate event enum in main module
qapi: add 'if' to top-level expressions
qapi: pass 'if' condition into QAPISchemaEntity objects
qapi: leave the ifcond attribute undefined until check()
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: add preprocessor conditions to generated QLit
qapi/commands: add #if conditions to commands
qapi/events: 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: rename QAPISchemaEnumType.values to .members
qapi: change enum visitor to take QAPISchemaMember
tests: modify visit_enum_type() in test-qapi to print members
qapi: factor out check_known_keys()
qapi: add a dictionnary form with 'name' key for enum members
qapi: add 'if' to enum members
qapi-event: add 'if' condition to implicit event enum
qapi: rename allow_dict to allow_implicit
qapi: add a dictionary form with 'type' key for members
qapi: add 'if' to implicit struct members
qapi: add an error in case a discriminator is conditionnal
qapi: add 'if' on union members
qapi: add 'if' to alternate members
qapi: add #if conditions to generated code members
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
build-sys: move qmp-introspect per target
qapi-commands: don't initialize command list in qmp_init_marshall()
RFC: qapi: learn to split schema by 'top-unit'
qapi: add a top-unit 'target' schema
qapi: make rtc-reset-reinjection and SEV 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: remove qmp_unregister_command()
RFC: make RTC_CHANGE per-target
qapi/block-core.json | 13 +-
qapi/char.json | 10 +-
qapi/migration.json | 12 +-
qapi/misc.json | 380 -----------
qapi/qapi-schema.json | 1 +
qapi/target.json | 415 ++++++++++++
qapi/ui.json | 75 ++-
scripts/qapi/commands.py | 43 +-
scripts/qapi/common.py | 599 +++++++++++++-----
scripts/qapi/doc.py | 46 +-
scripts/qapi/events.py | 45 +-
scripts/qapi/introspect.py | 57 +-
scripts/qapi/types.py | 98 +--
scripts/qapi/visit.py | 59 +-
include/qapi/qmp-event.h | 4 +
include/qapi/qmp/dispatch.h | 1 -
include/sysemu/arch_init.h | 11 -
target/i386/sev_i386.h | 2 +-
ui/vnc.h | 2 +
hmp.c | 9 +-
hw/ppc/spapr_rtc.c | 2 +-
hw/s390x/s390-skeys.c | 2 +-
hw/timer/mc146818rtc.c | 4 +-
migration/colo.c | 16 +-
monitor.c | 297 +++++----
qapi/qmp-event.c | 11 +
qapi/qmp-registry.c | 8 -
qga/main.c | 1 +
qmp.c | 72 +--
stubs/arch-query-cpu-def.c | 11 -
stubs/arch-query-cpu-model-baseline.c | 13 -
stubs/arch-query-cpu-model-comparison.c | 13 -
stubs/arch-query-cpu-model-expansion.c | 13 -
target/arm/helper.c | 3 +-
target/arm/monitor.c | 2 +-
target/i386/cpu.c | 6 +-
target/ppc/translate_init.c | 3 +-
target/s390x/cpu_models.c | 9 +-
tests/test-qmp-cmds.c | 7 +
tests/test-qobject-input-visitor.c | 1 -
Makefile | 1 +
Makefile.objs | 2 -
Makefile.target | 4 +
docs/devel/qapi-code-gen.txt | 38 ++
hmp-commands-info.hx | 2 +
stubs/Makefile.objs | 4 -
tests/Makefile.include | 14 +-
tests/qapi-schema/alternate-base.err | 2 +-
tests/qapi-schema/alternate-invalid-dict.err | 1 +
...ember.exit => alternate-invalid-dict.exit} | 0
tests/qapi-schema/alternate-invalid-dict.json | 4 +
...-member.out => alternate-invalid-dict.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-list.err | 1 +
tests/qapi-schema/bad-if-list.exit | 1 +
tests/qapi-schema/bad-if-list.json | 3 +
tests/qapi-schema/bad-if-list.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-bad-section.out | 13 +-
tests/qapi-schema/doc-good.json | 11 +-
tests/qapi-schema/doc-good.out | 23 +-
tests/qapi-schema/doc-good.texi | 10 +-
tests/qapi-schema/double-type.err | 2 +-
tests/qapi-schema/empty.out | 9 +-
tests/qapi-schema/enum-bad-member.err | 1 +
tests/qapi-schema/enum-bad-member.exit | 1 +
tests/qapi-schema/enum-bad-member.json | 2 +
tests/qapi-schema/enum-bad-member.out | 0
.../qapi-schema/enum-dict-member-unknown.err | 1 +
.../qapi-schema/enum-dict-member-unknown.exit | 1 +
.../qapi-schema/enum-dict-member-unknown.json | 2 +
.../qapi-schema/enum-dict-member-unknown.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/enum-missing-data.err | 2 +-
tests/qapi-schema/event-case.out | 9 +-
tests/qapi-schema/event-nest-struct.err | 2 +-
tests/qapi-schema/flat-union-inline.err | 2 +-
.../flat-union-invalid-if-discriminator.err | 1 +
.../flat-union-invalid-if-discriminator.exit | 1 +
.../flat-union-invalid-if-discriminator.json | 17 +
.../flat-union-invalid-if-discriminator.out | 0
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/nested-struct-data.err | 2 +-
tests/qapi-schema/qapi-schema-test.json | 46 +-
tests/qapi-schema/qapi-schema-test.out | 100 ++-
.../struct-member-invalid-dict.err | 1 +
.../struct-member-invalid-dict.exit | 1 +
.../struct-member-invalid-dict.json | 3 +
.../struct-member-invalid-dict.out | 0
tests/qapi-schema/test-qapi.py | 39 +-
.../qapi-schema/union-branch-invalid-dict.err | 1 +
.../union-branch-invalid-dict.exit | 1 +
.../union-branch-invalid-dict.json | 4 +
.../qapi-schema/union-branch-invalid-dict.out | 0
tests/qapi-schema/unknown-expr-key.err | 2 +-
tests/qapi-schema/unknown-expr-key.json | 2 +-
116 files changed, 1768 insertions(+), 1094 deletions(-)
create mode 100644 qapi/target.json
mode change 100644 => 100755 scripts/qapi/doc.py
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-invalid-dict.err
rename tests/qapi-schema/{enum-dict-member.exit => alternate-invalid-dict.exit} (100%)
create mode 100644 tests/qapi-schema/alternate-invalid-dict.json
rename tests/qapi-schema/{enum-dict-member.out => alternate-invalid-dict.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-list.err
create mode 100644 tests/qapi-schema/bad-if-list.exit
create mode 100644 tests/qapi-schema/bad-if-list.json
create mode 100644 tests/qapi-schema/bad-if-list.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-bad-member.err
create mode 100644 tests/qapi-schema/enum-bad-member.exit
create mode 100644 tests/qapi-schema/enum-bad-member.json
create mode 100644 tests/qapi-schema/enum-bad-member.out
create mode 100644 tests/qapi-schema/enum-dict-member-unknown.err
create mode 100644 tests/qapi-schema/enum-dict-member-unknown.exit
create mode 100644 tests/qapi-schema/enum-dict-member-unknown.json
create mode 100644 tests/qapi-schema/enum-dict-member-unknown.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/flat-union-invalid-if-discriminator.err
create mode 100644 tests/qapi-schema/flat-union-invalid-if-discriminator.exit
create mode 100644 tests/qapi-schema/flat-union-invalid-if-discriminator.json
create mode 100644 tests/qapi-schema/flat-union-invalid-if-discriminator.out
create mode 100644 tests/qapi-schema/struct-member-invalid-dict.err
create mode 100644 tests/qapi-schema/struct-member-invalid-dict.exit
create mode 100644 tests/qapi-schema/struct-member-invalid-dict.json
create mode 100644 tests/qapi-schema/struct-member-invalid-dict.out
create mode 100644 tests/qapi-schema/union-branch-invalid-dict.err
create mode 100644 tests/qapi-schema/union-branch-invalid-dict.exit
create mode 100644 tests/qapi-schema/union-branch-invalid-dict.json
create mode 100644 tests/qapi-schema/union-branch-invalid-dict.out
--
2.16.2.521.g9aa15f885a
^ permalink raw reply [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 01/49] qapi/visit: remove useless prefix argument
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-06-18 14:29 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 02/49] qapi/events: generate event enum in main module Marc-André Lureau
` (52 subsequent siblings)
53 siblings, 1 reply; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi/visit.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py
index 5d72d8936c..3c5ea1289e 100644
--- a/scripts/qapi/visit.py
+++ b/scripts/qapi/visit.py
@@ -293,7 +293,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor):
#include "qapi/qmp/qerror.h"
#include "%(visit)s.h"
''',
- visit=visit, prefix=self._prefix))
+ visit=visit))
self._genh.preamble_add(mcgen('''
#include "qapi/qapi-builtin-visit.h"
#include "%(types)s.h"
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 02/49] qapi/events: generate event enum in main module
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 01/49] qapi/visit: remove useless prefix argument Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-06-18 14:33 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 03/49] qapi: add 'if' to top-level expressions Marc-André Lureau
` (51 subsequent siblings)
53 siblings, 1 reply; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
The event generator produces an enum, and put it in the last visited
module. It fits better in the main module, since it's the set of all
visited events, from all modules.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi/events.py | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/scripts/qapi/events.py b/scripts/qapi/events.py
index 3dc523cf39..3e448ae523 100644
--- a/scripts/qapi/events.py
+++ b/scripts/qapi/events.py
@@ -180,8 +180,9 @@ class QAPISchemaGenEventVisitor(QAPISchemaModularCVisitor):
types=types))
def visit_end(self):
- self._genh.add(gen_enum(self._enum_name, self._event_names))
- self._genc.add(gen_enum_lookup(self._enum_name, self._event_names))
+ (genc, genh) = self._module[self._main_module]
+ genh.add(gen_enum(self._enum_name, self._event_names))
+ genc.add(gen_enum_lookup(self._enum_name, self._event_names))
def visit_event(self, name, info, arg_type, boxed):
self._genh.add(gen_event_send_decl(name, arg_type, boxed))
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 03/49] qapi: add 'if' to top-level expressions
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 01/49] qapi/visit: remove useless prefix argument Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 02/49] qapi/events: generate event enum in main module Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-06-19 7:57 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 04/49] qapi: pass 'if' condition into QAPISchemaEntity objects Marc-André Lureau
` (50 subsequent siblings)
53 siblings, 1 reply; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
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>
---
scripts/qapi/common.py | 35 ++++++++++++++++++++----
tests/test-qmp-cmds.c | 6 ++++
tests/Makefile.include | 6 ++++
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-list.err | 1 +
tests/qapi-schema/bad-if-list.exit | 1 +
tests/qapi-schema/bad-if-list.json | 3 ++
tests/qapi-schema/bad-if-list.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/qapi-schema-test.json | 20 ++++++++++++++
tests/qapi-schema/qapi-schema-test.out | 22 +++++++++++++++
21 files changed, 103 insertions(+), 6 deletions(-)
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-list.err
create mode 100644 tests/qapi-schema/bad-if-list.exit
create mode 100644 tests/qapi-schema/bad-if-list.json
create mode 100644 tests/qapi-schema/bad-if-list.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/scripts/qapi/common.py b/scripts/qapi/common.py
index 2c05e3c284..4f9e02b0b4 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -637,6 +637,27 @@ def add_name(name, info, meta, implicit=False):
all_names[name] = meta
+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.get('if')
+ if ifcond is None:
+ return
+ 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)
+
+
def check_type(info, source, value, allow_array=False,
allow_dict=False, allow_optional=False,
allow_metas=[]):
@@ -876,6 +897,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'"
@@ -904,28 +927,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', 'allow-oob'])
+ 'boxed', 'allow-oob', '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-cmds.c b/tests/test-qmp-cmds.c
index 93fbbb1b73..c25fc2100a 100644
--- a/tests/test-qmp-cmds.c
+++ b/tests/test-qmp-cmds.c
@@ -12,6 +12,12 @@
static QmpCommandList qmp_commands;
+/* #if defined(TEST_IF_STRUCT) && defined(TEST_IF_CMD) */
+void qmp_TestIfCmd(TestIfStruct *foo, Error **errp)
+{
+}
+/* #endif */
+
void qmp_user_def_cmd(Error **errp)
{
}
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 0b277036df..f77ad2ba3b 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -436,6 +436,10 @@ 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-if-list.json
qapi-schema += bad-type-bool.json
qapi-schema += bad-type-dict.json
qapi-schema += bad-type-int.json
@@ -933,6 +937,8 @@ $(patsubst %, check-%, $(check-qapi-schema-y)): check-%.json: $(SRC_PATH)/%.json
"TEST","$*.out")
@# Sanitize error messages (make them independent of build directory)
@perl -p -e 's|\Q$(SRC_PATH)\E/||g' $*.test.err | diff -u $(SRC_PATH)/$*.err -
+ @if test "$(QAPI_REGENERATE)" == 1 ; then cp $*.test.out $(SRC_PATH)/$*.out ; fi
+ @if test "$(QAPI_REGENERATE)" == 1 ; then cp $*.test.err $(SRC_PATH)/$*.err ; fi
@diff -u $(SRC_PATH)/$*.out $*.test.out
@diff -u $(SRC_PATH)/$*.exit $*.test.exit
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-list.err b/tests/qapi-schema/bad-if-list.err
new file mode 100644
index 0000000000..0af6316f78
--- /dev/null
+++ b/tests/qapi-schema/bad-if-list.err
@@ -0,0 +1 @@
+tests/qapi-schema/bad-if-list.json:2: 'if' condition '' makes no sense
diff --git a/tests/qapi-schema/bad-if-list.exit b/tests/qapi-schema/bad-if-list.exit
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/tests/qapi-schema/bad-if-list.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/bad-if-list.json b/tests/qapi-schema/bad-if-list.json
new file mode 100644
index 0000000000..49ced9b9ca
--- /dev/null
+++ b/tests/qapi-schema/bad-if-list.json
@@ -0,0 +1,3 @@
+# check invalid 'if' content
+{ 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
+ 'if': ['foo', ''] }
diff --git a/tests/qapi-schema/bad-if-list.out b/tests/qapi-schema/bad-if-list.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
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index c72dbd8050..b997b2d43d 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 012e7fc06a..b11682314c 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -230,3 +230,25 @@ object q_obj___org.qemu_x-command-arg
member d: __org.qemu_x-Alt optional=False
command __org.qemu_x-command q_obj___org.qemu_x-command-arg -> __org.qemu_x-Union1
gen=True success_response=True boxed=False
+object TestIfStruct
+ member foo: int optional=False
+enum TestIfEnum ['foo', 'bar']
+object q_obj_TestStruct-wrapper
+ member data: TestStruct optional=False
+enum TestIfUnionKind ['foo']
+object TestIfUnion
+ member type: TestIfUnionKind optional=False
+ tag type
+ case foo: q_obj_TestStruct-wrapper
+alternate TestIfAlternate
+ tag type
+ case foo: int
+ case bar: TestStruct
+object q_obj_TestIfCmd-arg
+ member foo: TestIfStruct optional=False
+command TestIfCmd q_obj_TestIfCmd-arg -> None
+ gen=True success_response=True boxed=False
+object q_obj_TestIfEvent-arg
+ member foo: TestIfStruct optional=False
+event TestIfEvent q_obj_TestIfEvent-arg
+ boxed=False
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 04/49] qapi: pass 'if' condition into QAPISchemaEntity objects
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (2 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 03/49] qapi: add 'if' to top-level expressions Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-06-19 8:09 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 05/49] qapi: leave the ifcond attribute undefined until check() Marc-André Lureau
` (49 subsequent siblings)
53 siblings, 1 reply; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
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 wrapped type's 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>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
---
scripts/qapi/common.py | 97 ++++++++++++++++++++++++++++--------------
1 file changed, 65 insertions(+), 32 deletions(-)
diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index 4f9e02b0b4..d8ab3d8f7f 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -1006,8 +1006,16 @@ def check_exprs(exprs):
# Schema compiler frontend
#
+def listify_cond(ifcond):
+ if not ifcond:
+ return []
+ if not isinstance(ifcond, list):
+ return [ifcond]
+ return ifcond
+
+
class QAPISchemaEntity(object):
- def __init__(self, name, info, doc):
+ def __init__(self, name, info, doc, ifcond=None):
assert name is None or isinstance(name, str)
self.name = name
self.module = None
@@ -1018,6 +1026,7 @@ class QAPISchemaEntity(object):
# such place).
self.info = info
self.doc = doc
+ self.ifcond = listify_cond(ifcond)
def c_name(self):
return c_name(self.name)
@@ -1150,8 +1159,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)
@@ -1186,7 +1195,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
@@ -1194,6 +1203,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
@@ -1215,11 +1225,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)
@@ -1407,8 +1418,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)
@@ -1444,9 +1455,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, allow_oob):
- 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
@@ -1485,8 +1496,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
@@ -1581,22 +1592,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):
@@ -1605,22 +1616,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
@@ -1640,7 +1666,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))
@@ -1652,18 +1679,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.items()]
@@ -1671,12 +1701,12 @@ class QAPISchema(object):
else:
variants = [self._make_simple_variant(key, value, info)
for (key, value) in data.items()]
- 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)))
@@ -1684,11 +1714,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.items()]
tag_member = QAPISchemaObjectTypeMember('type', 'QType', False)
self._def_entity(
- QAPISchemaAlternateType(name, info, doc,
+ QAPISchemaAlternateType(name, info, doc, ifcond,
QAPISchemaObjectTypeVariants(None,
tag_member,
variants)))
@@ -1701,13 +1732,14 @@ class QAPISchema(object):
success_response = expr.get('success-response', True)
boxed = expr.get('boxed', False)
allow_oob = expr.get('allow-oob', 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, allow_oob))
@@ -1715,10 +1747,11 @@ class QAPISchema(object):
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, exprs):
for expr_elem in exprs:
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 05/49] qapi: leave the ifcond attribute undefined until check()
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (3 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 04/49] qapi: pass 'if' condition into QAPISchemaEntity objects Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-06-19 9:06 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 06/49] qapi: add 'ifcond' to visitor methods Marc-André Lureau
` (48 subsequent siblings)
53 siblings, 1 reply; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
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.
Leave the ifcond attribute undefined until check().
Suggested-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
---
scripts/qapi/common.py | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index d8ab3d8f7f..eb07d641ab 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -1026,13 +1026,19 @@ class QAPISchemaEntity(object):
# such place).
self.info = info
self.doc = doc
- self.ifcond = listify_cond(ifcond)
+ self._ifcond = ifcond # self.ifcond is set only after .check()
def c_name(self):
return c_name(self.name)
def check(self, schema):
- pass
+ if isinstance(self._ifcond, QAPISchemaType):
+ # inherit the condition from a type
+ typ = self._ifcond
+ typ.check(schema)
+ self.ifcond = typ.ifcond
+ else:
+ self.ifcond = listify_cond(self._ifcond)
def is_implicit(self):
return not self.info
@@ -1169,6 +1175,7 @@ class QAPISchemaEnumType(QAPISchemaType):
self.prefix = prefix
def check(self, schema):
+ QAPISchemaType.check(self, schema)
seen = {}
for v in self.values:
v.check_clash(self.info, seen)
@@ -1201,8 +1208,10 @@ class QAPISchemaArrayType(QAPISchemaType):
self.element_type = None
def check(self, schema):
+ QAPISchemaType.check(self, schema)
self.element_type = schema.lookup_type(self._element_type_name)
assert self.element_type
+ self.element_type.check(schema)
self.ifcond = self.element_type.ifcond
def is_implicit(self):
@@ -1245,6 +1254,7 @@ class QAPISchemaObjectType(QAPISchemaType):
self.members = None
def check(self, schema):
+ QAPISchemaType.check(self, schema)
if self.members is False: # check for cycles
raise QAPISemError(self.info,
"Object %s contains itself" % self.name)
@@ -1427,6 +1437,7 @@ class QAPISchemaAlternateType(QAPISchemaType):
self.variants = variants
def check(self, schema):
+ QAPISchemaType.check(self, schema)
self.variants.tag_member.check(schema)
# Not calling self.variants.check_clash(), because there's nothing
# to clash with
@@ -1470,6 +1481,7 @@ class QAPISchemaCommand(QAPISchemaEntity):
self.allow_oob = allow_oob
def check(self, schema):
+ QAPISchemaEntity.check(self, schema)
if self._arg_type_name:
self.arg_type = schema.lookup_type(self._arg_type_name)
assert (isinstance(self.arg_type, QAPISchemaObjectType) or
@@ -1504,6 +1516,7 @@ class QAPISchemaEvent(QAPISchemaEntity):
self.boxed = boxed
def check(self, schema):
+ QAPISchemaEntity.check(self, schema)
if self._arg_type_name:
self.arg_type = schema.lookup_type(self._arg_type_name)
assert (isinstance(self.arg_type, QAPISchemaObjectType) or
@@ -1633,7 +1646,7 @@ class QAPISchema(object):
# 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
+ assert ifcond == typ._ifcond
else:
self._def_entity(QAPISchemaObjectType(name, info, doc, ifcond,
None, members, None))
@@ -1679,7 +1692,7 @@ class QAPISchema(object):
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,
+ typ, info, None, self.lookup_type(typ),
'wrapper', [self._make_member('data', typ, info)])
return QAPISchemaObjectTypeVariant(case, typ)
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 06/49] qapi: add 'ifcond' to visitor methods
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (4 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 05/49] qapi: leave the ifcond attribute undefined until check() Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-06-21 8:18 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 07/49] qapi: mcgen() shouldn't indent # lines Marc-André Lureau
` (47 subsequent siblings)
53 siblings, 1 reply; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
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>
---
scripts/qapi/commands.py | 2 +-
scripts/qapi/common.py | 31 ++++++++++++++------------
scripts/qapi/doc.py | 10 ++++-----
scripts/qapi/events.py | 2 +-
scripts/qapi/introspect.py | 12 +++++-----
scripts/qapi/types.py | 8 +++----
scripts/qapi/visit.py | 8 +++----
tests/qapi-schema/qapi-schema-test.out | 9 ++++++++
tests/qapi-schema/test-qapi.py | 19 +++++++++++-----
9 files changed, 61 insertions(+), 40 deletions(-)
mode change 100644 => 100755 scripts/qapi/doc.py
diff --git a/scripts/qapi/commands.py b/scripts/qapi/commands.py
index 0c5da3a54d..e2366b4801 100644
--- a/scripts/qapi/commands.py
+++ b/scripts/qapi/commands.py
@@ -275,7 +275,7 @@ void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds);
c_prefix=c_name(self._prefix, protect=False)))
genc.add(gen_registry(self._regy, self._prefix))
- 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, allow_oob):
if not gen:
return
diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index eb07d641ab..bc4ecd6c76 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -1067,26 +1067,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, allow_oob):
pass
- def visit_event(self, name, info, arg_type, boxed):
+ def visit_event(self, name, info, ifcond, arg_type, boxed):
pass
@@ -1196,7 +1196,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)
@@ -1230,7 +1230,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):
@@ -1312,9 +1313,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)
@@ -1459,7 +1460,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
@@ -1501,7 +1503,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, self.allow_oob)
@@ -1533,7 +1535,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/doc.py b/scripts/qapi/doc.py
old mode 100644
new mode 100755
index 9b312b2c51..d5cfd2336b
--- a/scripts/qapi/doc.py
+++ b/scripts/qapi/doc.py
@@ -204,14 +204,14 @@ class QAPISchemaGenDocVisitor(qapi.common.QAPISchemaVisitor):
def write(self, output_dir):
self._gen.write(output_dir, self._prefix + 'qapi-doc.texi')
- def visit_enum_type(self, name, info, values, prefix):
+ def visit_enum_type(self, name, info, ifcond, values, prefix):
doc = self.cur_doc
self._gen.add(TYPE_FMT(type='Enum',
name=doc.symbol,
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
@@ -220,13 +220,13 @@ class QAPISchemaGenDocVisitor(qapi.common.QAPISchemaVisitor):
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
self._gen.add(TYPE_FMT(type='Alternate',
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, allow_oob):
doc = self.cur_doc
if boxed:
@@ -240,7 +240,7 @@ class QAPISchemaGenDocVisitor(qapi.common.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
self._gen.add(MSG_FMT(type='Event',
name=doc.symbol,
diff --git a/scripts/qapi/events.py b/scripts/qapi/events.py
index 3e448ae523..26ae00f6f7 100644
--- a/scripts/qapi/events.py
+++ b/scripts/qapi/events.py
@@ -184,7 +184,7 @@ class QAPISchemaGenEventVisitor(QAPISchemaModularCVisitor):
genh.add(gen_enum(self._enum_name, self._event_names))
genc.add(gen_enum_lookup(self._enum_name, self._event_names))
- def visit_event(self, name, info, arg_type, boxed):
+ def visit_event(self, name, info, ifcond, arg_type, boxed):
self._genh.add(gen_event_send_decl(name, arg_type, boxed))
self._genc.add(gen_event_send(name, arg_type, boxed, self._enum_name))
self._event_names.append(name)
diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index f9e67e8227..6cb95cf53e 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -152,26 +152,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, allow_oob):
arg_type = arg_type or self._schema.the_empty_object_type
ret_type = ret_type or self._schema.the_empty_object_type
@@ -180,7 +180,7 @@ const QLitObject %(c_name)s = %(c_string)s;
'ret-type': self._use_type(ret_type),
'allow-oob': allow_oob})
- 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 64d9c0fb37..298a80db62 100644
--- a/scripts/qapi/types.py
+++ b/scripts/qapi/types.py
@@ -206,16 +206,16 @@ class QAPISchemaGenTypeVisitor(QAPISchemaModularCVisitor):
self._genh.add(gen_type_cleanup_decl(name))
self._genc.add(gen_type_cleanup(name))
- def visit_enum_type(self, name, info, values, prefix):
+ def visit_enum_type(self, name, info, ifcond, values, prefix):
self._genh.preamble_add(gen_enum(name, values, prefix))
self._genc.add(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):
self._genh.preamble_add(gen_fwd_object_or_array(name))
self._genh.add(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
@@ -229,7 +229,7 @@ class QAPISchemaGenTypeVisitor(QAPISchemaModularCVisitor):
# 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._genh.preamble_add(gen_fwd_object_or_array(name))
self._genh.add(gen_object(name, None,
[variants.tag_member], variants))
diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py
index 3c5ea1289e..9ea2e04f81 100644
--- a/scripts/qapi/visit.py
+++ b/scripts/qapi/visit.py
@@ -301,15 +301,15 @@ class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor):
''',
types=types))
- def visit_enum_type(self, name, info, values, prefix):
+ def visit_enum_type(self, name, info, ifcond, values, prefix):
self._genh.add(gen_visit_decl(name, scalar=True))
self._genc.add(gen_visit_enum(name))
- def visit_array_type(self, name, info, element_type):
+ def visit_array_type(self, name, info, ifcond, element_type):
self._genh.add(gen_visit_decl(name))
self._genc.add(gen_visit_list(name, element_type))
- 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
@@ -322,7 +322,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor):
self._genh.add(gen_visit_decl(name))
self._genc.add(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._genh.add(gen_visit_decl(name))
self._genc.add(gen_visit_alternate(name, variants))
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index b11682314c..8fe9d7a3a8 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -232,23 +232,32 @@ command __org.qemu_x-command q_obj___org.qemu_x-command-arg -> __org.qemu_x-Unio
gen=True success_response=True boxed=False
object TestIfStruct
member foo: int optional=False
+ if ['defined(TEST_IF_STRUCT)']
enum TestIfEnum ['foo', 'bar']
+ if ['defined(TEST_IF_ENUM)']
object q_obj_TestStruct-wrapper
member data: TestStruct optional=False
enum TestIfUnionKind ['foo']
+ if ['defined(TEST_IF_UNION) && 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)']
alternate TestIfAlternate
tag type
case foo: int
case bar: TestStruct
+ if ['defined(TEST_IF_ALT) && defined(TEST_IF_STRUCT)']
object q_obj_TestIfCmd-arg
member foo: TestIfStruct optional=False
+ if ['defined(TEST_IF_CMD)', '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)']
object q_obj_TestIfEvent-arg
member foo: TestIfStruct optional=False
+ if ['defined(TEST_IF_EVT) && defined(TEST_IF_STRUCT)']
event TestIfEvent q_obj_TestIfEvent-arg
boxed=False
+ if ['defined(TEST_IF_EVT) && defined(TEST_IF_STRUCT)']
diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
index 10e68b01d9..6d25a37dda 100644
--- a/tests/qapi-schema/test-qapi.py
+++ b/tests/qapi-schema/test-qapi.py
@@ -23,12 +23,13 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
def visit_include(self, name, info):
print('include %s' % name)
- 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)
@@ -36,21 +37,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, allow_oob):
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):
@@ -59,6 +64,10 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
for v in variants.variants:
print(' case %s: %s' % (v.name, v.type.name))
+ @staticmethod
+ def _print_if(ifcond, indent=4):
+ if ifcond:
+ print('%sif %s' % (' ' * indent, ifcond))
try:
schema = QAPISchema(sys.argv[1])
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 07/49] qapi: mcgen() shouldn't indent # lines
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (5 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 06/49] qapi: add 'ifcond' to visitor methods Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-06-20 15:14 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 08/49] qapi: add #if/#endif helpers Marc-André Lureau
` (46 subsequent siblings)
53 siblings, 1 reply; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
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/common.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index bc4ecd6c76..47efe79758 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -1931,8 +1931,8 @@ 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),
- indent + r'\g<0>', raw)
+ raw = re.subn(re.compile(r'^(?!(#|$))', re.MULTILINE),
+ indent, raw)
raw = raw[0]
return re.sub(re.escape(eatspace) + r' *', '', raw)
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 08/49] qapi: add #if/#endif helpers
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (6 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 07/49] qapi: mcgen() shouldn't indent # lines Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-06-20 16:01 ` Markus Armbruster
2018-06-21 7:06 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 09/49] qapi-introspect: modify to_qlit() to append ', ' on level > 0 Marc-André Lureau
` (45 subsequent siblings)
53 siblings, 2 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
Add helpers to wrap generated code with #if/#endif lines.
Add QAPIGenCSnippet class to write C snippet code, make QAPIGenC
inherit from it, for full C files with copyright headers etc.
Add a 'with' statement context manager that will be used to wrap
generator visitor methods. The manager will check if code was
generated before adding #if/#endif lines on QAPIGenCSnippet
objects. Used in the following patches.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi/common.py | 82 +++++++++++++++++++++++++++++++++++++++---
1 file changed, 78 insertions(+), 4 deletions(-)
diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index 47efe79758..60c1d0a783 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -12,6 +12,7 @@
# See the COPYING file in the top-level directory.
from __future__ import print_function
+from contextlib import contextmanager
import errno
import os
import re
@@ -1964,6 +1965,40 @@ def guardend(name):
name=guardname(name))
+def gen_if(ifcond):
+ ret = ''
+ for ifc in ifcond:
+ ret += mcgen('''
+#if %(cond)s
+''', cond=ifc)
+ return ret
+
+
+def gen_endif(ifcond):
+ ret = ''
+ for ifc in reversed(ifcond):
+ ret += mcgen('''
+#endif /* %(cond)s */
+''', cond=ifc)
+ return ret
+
+
+def wrap_ifcond(ifcond, before, after):
+ if ifcond is None or before == after:
+ return after
+
+ assert after.startswith(before)
+ out = before
+ added = after[len(before):]
+ if added[0] == '\n':
+ out += '\n'
+ added = added[1:]
+ out += gen_if(ifcond)
+ out += added
+ out += gen_endif(ifcond)
+ return out
+
+
def gen_enum_lookup(name, values, prefix=None):
ret = mcgen('''
@@ -2054,6 +2089,7 @@ class QAPIGen(object):
def __init__(self):
self._preamble = ''
self._body = ''
+ self._ifcond = None
def preamble_add(self, text):
self._preamble += text
@@ -2061,6 +2097,23 @@ class QAPIGen(object):
def add(self, text):
self._body += text
+ def start_if(self, ifcond):
+ self._ifcond = ifcond
+ self._start_if_body = self._body
+ self._start_if_preamble = self._preamble
+
+ def _wrap_ifcond(self):
+ pass
+
+ def end_if(self):
+ self._wrap_ifcond()
+ self._ifcond = None
+
+ def get_content(self, fname=None):
+ assert self._ifcond is None
+ return (self._top(fname) + self._preamble + self._body
+ + self._bottom(fname))
+
def _top(self, fname):
return ''
@@ -2078,8 +2131,7 @@ class QAPIGen(object):
raise
fd = os.open(pathname, os.O_RDWR | os.O_CREAT, 0o666)
f = os.fdopen(fd, 'r+')
- text = (self._top(fname) + self._preamble + self._body
- + self._bottom(fname))
+ text = self.get_content(fname)
oldtext = f.read(len(text) + 1)
if text != oldtext:
f.seek(0)
@@ -2088,10 +2140,32 @@ class QAPIGen(object):
f.close()
-class QAPIGenC(QAPIGen):
+@contextmanager
+def ifcontext(ifcond, *args):
+ saved = []
+ for arg in args:
+ arg.start_if(ifcond)
+ yield
+ for arg in args:
+ arg.end_if()
- def __init__(self, blurb, pydoc):
+
+class QAPIGenCSnippet(QAPIGen):
+
+ def __init__(self):
QAPIGen.__init__(self)
+
+ def _wrap_ifcond(self):
+ self._body = wrap_ifcond(self._ifcond,
+ self._start_if_body, self._body)
+ self._preamble = wrap_ifcond(self._ifcond,
+ self._start_if_preamble, self._preamble)
+
+
+class QAPIGenC(QAPIGenCSnippet):
+
+ def __init__(self, blurb, pydoc):
+ QAPIGenCSnippet.__init__(self)
self._blurb = blurb
self._copyright = '\n * '.join(re.findall(r'^Copyright .*', pydoc,
re.MULTILINE))
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 09/49] qapi-introspect: modify to_qlit() to append ', ' on level > 0
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (7 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 08/49] qapi: add #if/#endif helpers Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 10/49] qapi-introspect: add preprocessor conditions to generated QLit Marc-André Lureau
` (44 subsequent siblings)
53 siblings, 0 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
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>
Reviewed-by: Markus Armbruster <armbru@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 6cb95cf53e..1a8eb9e33e 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -30,7 +30,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 = []
@@ -45,6 +45,8 @@ def to_qlit(obj, level=0, suppress_first_indent=False):
ret += 'QLIT_QBOOL(%s)' % ('true' if obj else 'false')
else:
assert False # not implemented
+ if level > 0:
+ ret += ','
return ret
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 10/49] qapi-introspect: add preprocessor conditions to generated QLit
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (8 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 09/49] qapi-introspect: modify to_qlit() to append ', ' on level > 0 Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-06-21 13:05 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 11/49] qapi/commands: add #if conditions to commands Marc-André Lureau
` (43 subsequent siblings)
53 siblings, 1 reply; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
The generator will take (obj, condition) tuples to wrap generated QLit
objects for 'obj' with #if/#endif conditions.
This commit adds 'ifcond' condition to top-level QLit objects.
See generated tests/test-qmp-introspect.c. Example diff after this patch:
--- before 2018-01-08 11:55:24.757083654 +0100
+++ tests/test-qmp-introspect.c 2018-01-08 13:08:44.477641629 +0100
@@ -51,6 +51,8 @@
{ "name", QLIT_QSTR("EVENT_F"), },
{}
})),
+#if defined(TEST_IF_CMD)
+#if defined(TEST_IF_STRUCT)
QLIT_QDICT(((QLitDictEntry[]) {
{ "arg-type", QLIT_QSTR("5"), },
{ "meta-type", QLIT_QSTR("command"), },
@@ -58,12 +60,16 @@
{ "ret-type", QLIT_QSTR("0"), },
{}
})),
+#endif /* defined(TEST_IF_STRUCT) */
+#endif /* defined(TEST_IF_CMD) */
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi/introspect.py | 31 +++++++++++++++++++++----------
1 file changed, 21 insertions(+), 10 deletions(-)
diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index 1a8eb9e33e..cb4825f134 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -18,6 +18,15 @@ 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)
+ endif = gen_endif(ifcond)
+ if endif:
+ ret += '\n' + endif
+ return ret
+
ret = ''
if not suppress_first_indent:
ret += indent(level)
@@ -26,7 +35,7 @@ def to_qlit(obj, level=0, suppress_first_indent=False):
elif isinstance(obj, str):
ret += 'QLIT_QSTR(' + to_c_string(obj) + ')'
elif isinstance(obj, list):
- elts = [to_qlit(elt, level + 1)
+ elts = [to_qlit(elt, level + 1).strip('\n')
for elt in obj]
elts.append(indent(level + 1) + "{}")
ret += 'QLIT_QLIST(((QLitObject[]) {\n'
@@ -131,12 +140,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)}
@@ -152,26 +161,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}, [])
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, allow_oob):
@@ -180,11 +190,12 @@ const QLitObject %(c_name)s = %(c_string)s;
self._gen_qlit(name, 'command',
{'arg-type': self._use_type(arg_type),
'ret-type': self._use_type(ret_type),
- 'allow-oob': allow_oob})
+ 'allow-oob': allow_oob}, 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)
def gen_introspect(schema, output_dir, prefix, opt_unmask):
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 11/49] qapi/commands: add #if conditions to commands
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (9 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 10/49] qapi-introspect: add preprocessor conditions to generated QLit Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-06-21 14:35 ` Markus Armbruster
2018-06-22 8:34 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 12/49] qapi/events: add #if conditions to events Marc-André Lureau
` (42 subsequent siblings)
53 siblings, 2 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
Wrap generated code with #if/#endif using an 'ifcontext' on
QAPIGenCSnippet objects.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi/commands.py | 19 ++++++++++---------
tests/test-qmp-cmds.c | 4 ++--
2 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/scripts/qapi/commands.py b/scripts/qapi/commands.py
index e2366b4801..40bb680b7c 100644
--- a/scripts/qapi/commands.py
+++ b/scripts/qapi/commands.py
@@ -237,7 +237,7 @@ class QAPISchemaGenCommandVisitor(QAPISchemaModularCVisitor):
QAPISchemaModularCVisitor.__init__(
self, prefix, 'qapi-commands',
' * Schema-defined QAPI/QMP commands', __doc__)
- self._regy = ''
+ self._regy = QAPIGenCSnippet()
self._visited_ret_types = {}
def _begin_module(self, name):
@@ -273,19 +273,20 @@ class QAPISchemaGenCommandVisitor(QAPISchemaModularCVisitor):
void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds);
''',
c_prefix=c_name(self._prefix, protect=False)))
- genc.add(gen_registry(self._regy, self._prefix))
+ genc.add(gen_registry(self._regy.get_content(), self._prefix))
def visit_command(self, name, info, ifcond, arg_type, ret_type,
gen, success_response, boxed, allow_oob):
if not gen:
return
- self._genh.add(gen_command_decl(name, arg_type, boxed, ret_type))
- if ret_type and ret_type not in self._visited_ret_types[self._genc]:
- self._visited_ret_types[self._genc].add(ret_type)
- self._genc.add(gen_marshal_output(ret_type))
- self._genh.add(gen_marshal_decl(name))
- self._genc.add(gen_marshal(name, arg_type, boxed, ret_type))
- self._regy += gen_register_command(name, success_response, allow_oob)
+ with ifcontext(ifcond, self._genh, self._genc, self._regy):
+ self._genh.add(gen_command_decl(name, arg_type, boxed, ret_type))
+ if ret_type and ret_type not in self._visited_ret_types[self._genc]:
+ self._visited_ret_types[self._genc].add(ret_type)
+ self._genc.add(gen_marshal_output(ret_type))
+ self._genh.add(gen_marshal_decl(name))
+ self._genc.add(gen_marshal(name, arg_type, boxed, ret_type))
+ self._regy.add(gen_register_command(name, success_response, allow_oob))
def gen_commands(schema, output_dir, prefix):
diff --git a/tests/test-qmp-cmds.c b/tests/test-qmp-cmds.c
index c25fc2100a..e675722593 100644
--- a/tests/test-qmp-cmds.c
+++ b/tests/test-qmp-cmds.c
@@ -12,11 +12,11 @@
static QmpCommandList qmp_commands;
-/* #if defined(TEST_IF_STRUCT) && defined(TEST_IF_CMD) */
+#if defined(TEST_IF_STRUCT) && defined(TEST_IF_CMD)
void qmp_TestIfCmd(TestIfStruct *foo, Error **errp)
{
}
-/* #endif */
+#endif
void qmp_user_def_cmd(Error **errp)
{
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 12/49] qapi/events: add #if conditions to events
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (10 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 11/49] qapi/commands: add #if conditions to commands Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-06-21 14:40 ` Markus Armbruster
2018-06-22 9:02 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 13/49] qapi-types: refactor variants handling Marc-André Lureau
` (41 subsequent siblings)
53 siblings, 2 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
Wrap generated code with #if/#endif using an 'ifcontext' on
QAPIGenCSnippet objects.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi/events.py | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/scripts/qapi/events.py b/scripts/qapi/events.py
index 26ae00f6f7..dae03e3d88 100644
--- a/scripts/qapi/events.py
+++ b/scripts/qapi/events.py
@@ -185,8 +185,9 @@ class QAPISchemaGenEventVisitor(QAPISchemaModularCVisitor):
genc.add(gen_enum_lookup(self._enum_name, self._event_names))
def visit_event(self, name, info, ifcond, arg_type, boxed):
- self._genh.add(gen_event_send_decl(name, arg_type, boxed))
- self._genc.add(gen_event_send(name, arg_type, boxed, self._enum_name))
+ with ifcontext(ifcond, self._genh, self._genc):
+ self._genh.add(gen_event_send_decl(name, arg_type, boxed))
+ self._genc.add(gen_event_send(name, arg_type, boxed, self._enum_name))
self._event_names.append(name)
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 13/49] qapi-types: refactor variants handling
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (11 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 12/49] qapi/events: add #if conditions to events Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-06-21 15:54 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 14/49] qapi-types: add #if conditions to types & visitors Marc-André Lureau
` (40 subsequent siblings)
53 siblings, 1 reply; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
Generate variants objects outside gen_object(). This will allow to
easily wrap gen_object() with ifcond_decorator in the following patch.
gen_variants_objects() calls gen_object() for each variants, so it
remains guarded for each generated variant object.
self._gen_type_cleanup(name) is factored out in _gen_object(), helping
generated code to be wrapped by the same condition in the following
patch.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi/types.py | 38 +++++++++++++++++++++++---------------
1 file changed, 23 insertions(+), 15 deletions(-)
diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py
index 298a80db62..3d9b0f9a07 100644
--- a/scripts/qapi/types.py
+++ b/scripts/qapi/types.py
@@ -55,23 +55,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():
@@ -215,11 +219,7 @@ class QAPISchemaGenTypeVisitor(QAPISchemaModularCVisitor):
self._genh.add(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._genh.preamble_add(gen_fwd_object_or_array(name))
+ def _gen_object(self, name, info, ifcond, base, members, variants):
self._genh.add(gen_object(name, base, members, variants))
if base and not base.is_implicit():
self._genh.add(gen_upcast(name, base))
@@ -229,11 +229,19 @@ class QAPISchemaGenTypeVisitor(QAPISchemaModularCVisitor):
# 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._genh.preamble_add(gen_fwd_object_or_array(name))
+ self._genh.add(gen_variants_objects(variants))
+ self._gen_object(name, info, None, base, members, variants)
+
def visit_alternate_type(self, name, info, ifcond, variants):
self._genh.preamble_add(gen_fwd_object_or_array(name))
- self._genh.add(gen_object(name, None,
- [variants.tag_member], variants))
- self._gen_type_cleanup(name)
+ self._genh.add(gen_variants_objects(variants))
+ self._gen_object(name, info, None, None,
+ [variants.tag_member], variants)
def gen_types(schema, output_dir, prefix, opt_builtins):
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 14/49] qapi-types: add #if conditions to types & visitors
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (12 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 13/49] qapi-types: refactor variants handling Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-06-21 16:12 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 15/49] qapi: do not define enumeration value explicitely Marc-André Lureau
` (39 subsequent siblings)
53 siblings, 1 reply; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
Types & visitors are coupled and must be handled together to avoid
temporary build regression.
Wrap generated types/visitor code with #if/#endif using the context
helpers.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi/types.py | 46 ++++++++++++++++++++++++++-----------------
scripts/qapi/visit.py | 33 ++++++++++++++++++-------------
2 files changed, 47 insertions(+), 32 deletions(-)
diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py
index 3d9b0f9a07..ce4c91206c 100644
--- a/scripts/qapi/types.py
+++ b/scripts/qapi/types.py
@@ -61,8 +61,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
@@ -206,41 +208,49 @@ class QAPISchemaGenTypeVisitor(QAPISchemaModularCVisitor):
# gen_object() is recursive, ensure it doesn't visit the empty type
objects_seen.add(schema.the_empty_object_type.name)
- def _gen_type_cleanup(self, name):
- self._genh.add(gen_type_cleanup_decl(name))
- self._genc.add(gen_type_cleanup(name))
+ def _gen_type_cleanup(self, name, ifcond):
+ with ifcontext(ifcond, self._genh, self._genc):
+ self._genh.add(gen_type_cleanup_decl(name))
+ self._genc.add(gen_type_cleanup(name))
def visit_enum_type(self, name, info, ifcond, values, prefix):
- self._genh.preamble_add(gen_enum(name, values, prefix))
- self._genc.add(gen_enum_lookup(name, values, prefix))
+ with ifcontext(ifcond, self._genh, self._genc):
+ self._genh.preamble_add(gen_enum(name, values, prefix))
+ self._genc.add(gen_enum_lookup(name, values, prefix))
def visit_array_type(self, name, info, ifcond, element_type):
- self._genh.preamble_add(gen_fwd_object_or_array(name))
- self._genh.add(gen_array(name, element_type))
- self._gen_type_cleanup(name)
+ with ifcontext(ifcond, self._genh):
+ self._genh.preamble_add(gen_fwd_object_or_array(name))
+ self._genh.add(gen_array(name, element_type))
+ self._gen_type_cleanup(name, ifcond)
def _gen_object(self, name, info, ifcond, base, members, variants):
- self._genh.add(gen_object(name, base, members, variants))
- if base and not base.is_implicit():
- self._genh.add(gen_upcast(name, base))
- # TODO Worth changing the visitor signature, so we could
- # directly use rather than repeat type.is_implicit()?
+ with ifcontext(ifcond, self._genh):
+ self._genh.add(gen_object(name, base, members, variants))
+ if base and not base.is_implicit():
+ self._genh.add(gen_upcast(name, base))
+ # TODO Worth changing the visitor signature, so we could
+ # directly use rather than repeat type.is_implicit()?
if not name.startswith('q_'):
# implicit types won't be directly allocated/freed
- self._gen_type_cleanup(name)
+ self._gen_type_cleanup(name, ifcond)
+
+ def _gen_fwd_object_or_array(self, name, ifcond):
+ with ifcontext(ifcond, self._genh):
+ self._genh.preamble_add(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._genh.preamble_add(gen_fwd_object_or_array(name))
+ self._gen_fwd_object_or_array(name, ifcond)
self._genh.add(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._genh.preamble_add(gen_fwd_object_or_array(name))
+ self._gen_fwd_object_or_array(name, ifcond)
self._genh.add(gen_variants_objects(variants))
- self._gen_object(name, info, None, None,
+ self._gen_object(name, info, ifcond, None,
[variants.tag_member], variants)
diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py
index 9ea2e04f81..e4a62ce030 100644
--- a/scripts/qapi/visit.py
+++ b/scripts/qapi/visit.py
@@ -302,29 +302,34 @@ class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor):
types=types))
def visit_enum_type(self, name, info, ifcond, values, prefix):
- self._genh.add(gen_visit_decl(name, scalar=True))
- self._genc.add(gen_visit_enum(name))
+ with ifcontext(ifcond, self._genh, self._genc):
+ self._genh.add(gen_visit_decl(name, scalar=True))
+ self._genc.add(gen_visit_enum(name))
def visit_array_type(self, name, info, ifcond, element_type):
- self._genh.add(gen_visit_decl(name))
- self._genc.add(gen_visit_list(name, element_type))
+ with ifcontext(ifcond, self._genh, self._genc):
+ self._genh.add(gen_visit_decl(name))
+ self._genc.add(gen_visit_list(name, element_type))
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._genh.add(gen_visit_members_decl(name))
- self._genc.add(gen_visit_object_members(name, base, members, variants))
- # TODO Worth changing the visitor signature, so we could
- # directly use rather than repeat type.is_implicit()?
- if not name.startswith('q_'):
- # only explicit types need an allocating visit
- self._genh.add(gen_visit_decl(name))
- self._genc.add(gen_visit_object(name, base, members, variants))
+ with ifcontext(ifcond, self._genh, self._genc):
+ self._genh.add(gen_visit_members_decl(name))
+ self._genc.add(gen_visit_object_members(name, base,
+ members, variants))
+ # TODO Worth changing the visitor signature, so we could
+ # directly use rather than repeat type.is_implicit()?
+ if not name.startswith('q_'):
+ # only explicit types need an allocating visit
+ self._genh.add(gen_visit_decl(name))
+ self._genc.add(gen_visit_object(name, base, members, variants))
def visit_alternate_type(self, name, info, ifcond, variants):
- self._genh.add(gen_visit_decl(name))
- self._genc.add(gen_visit_alternate(name, variants))
+ with ifcontext(ifcond, self._genh, self._genc):
+ self._genh.add(gen_visit_decl(name))
+ self._genc.add(gen_visit_alternate(name, variants))
def gen_visit(schema, output_dir, prefix, opt_builtins):
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 15/49] qapi: do not define enumeration value explicitely
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (13 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 14/49] qapi-types: add #if conditions to types & visitors Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-06-22 8:08 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 16/49] qapi: rename QAPISchemaEnumType.values to .members Marc-André Lureau
` (38 subsequent siblings)
53 siblings, 1 reply; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
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/common.py | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index 60c1d0a783..68a567f53f 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -2032,14 +2032,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.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 16/49] qapi: rename QAPISchemaEnumType.values to .members
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (14 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 15/49] qapi: do not define enumeration value explicitely Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-06-22 12:24 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 17/49] qapi: change enum visitor to take QAPISchemaMember Marc-André Lureau
` (37 subsequent siblings)
53 siblings, 1 reply; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
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.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi/common.py | 36 +++++++++++++++++-----------------
scripts/qapi/doc.py | 2 +-
scripts/qapi/introspect.py | 4 ++--
scripts/qapi/types.py | 6 +++---
scripts/qapi/visit.py | 2 +-
tests/qapi-schema/test-qapi.py | 4 ++--
6 files changed, 27 insertions(+), 27 deletions(-)
diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index 68a567f53f..ea5cdfe3be 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -1068,7 +1068,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):
@@ -1166,22 +1166,22 @@ 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):
QAPISchemaType.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()
@@ -1191,7 +1191,7 @@ 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'
@@ -1999,19 +1999,19 @@ def wrap_ifcond(ifcond, before, after):
return out
-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, prefix)
ret += mcgen('''
[%(index)s] = "%(value)s",
''',
- index=index, value=value)
+ index=index, value=m)
ret += mcgen('''
},
@@ -2022,9 +2022,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 + ['_MAX']
ret = mcgen('''
@@ -2032,11 +2032,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, prefix))
ret += mcgen('''
} %(c_name)s;
diff --git a/scripts/qapi/doc.py b/scripts/qapi/doc.py
index d5cfd2336b..6c2bf98e1d 100755
--- a/scripts/qapi/doc.py
+++ b/scripts/qapi/doc.py
@@ -204,7 +204,7 @@ class QAPISchemaGenDocVisitor(qapi.common.QAPISchemaVisitor):
def write(self, output_dir):
self._gen.write(output_dir, self._prefix + 'qapi-doc.texi')
- def visit_enum_type(self, name, info, ifcond, values, prefix):
+ def visit_enum_type(self, name, info, ifcond, members, prefix):
doc = self.cur_doc
self._gen.add(TYPE_FMT(type='Enum',
name=doc.symbol,
diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index cb4825f134..66f7fd00a9 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -163,8 +163,8 @@ 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, 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': 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 ce4c91206c..5b790cb41d 100644
--- a/scripts/qapi/types.py
+++ b/scripts/qapi/types.py
@@ -213,10 +213,10 @@ class QAPISchemaGenTypeVisitor(QAPISchemaModularCVisitor):
self._genh.add(gen_type_cleanup_decl(name))
self._genc.add(gen_type_cleanup(name))
- def visit_enum_type(self, name, info, ifcond, values, prefix):
+ def visit_enum_type(self, name, info, ifcond, members, prefix):
with ifcontext(ifcond, self._genh, self._genc):
- self._genh.preamble_add(gen_enum(name, values, prefix))
- self._genc.add(gen_enum_lookup(name, values, prefix))
+ self._genh.preamble_add(gen_enum(name, members, prefix))
+ self._genc.add(gen_enum_lookup(name, members, prefix))
def visit_array_type(self, name, info, ifcond, element_type):
with ifcontext(ifcond, self._genh):
diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py
index e4a62ce030..ee776386ae 100644
--- a/scripts/qapi/visit.py
+++ b/scripts/qapi/visit.py
@@ -301,7 +301,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor):
''',
types=types))
- def visit_enum_type(self, name, info, ifcond, values, prefix):
+ def visit_enum_type(self, name, info, ifcond, members, prefix):
with ifcontext(ifcond, self._genh, self._genc):
self._genh.add(gen_visit_decl(name, scalar=True))
self._genc.add(gen_visit_enum(name))
diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
index 6d25a37dda..f4b8feb9bc 100644
--- a/tests/qapi-schema/test-qapi.py
+++ b/tests/qapi-schema/test-qapi.py
@@ -23,8 +23,8 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
def visit_include(self, name, info):
print('include %s' % name)
- 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 %s' % (name, members))
if prefix:
print(' prefix %s' % prefix)
self._print_if(ifcond)
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 17/49] qapi: change enum visitor to take QAPISchemaMember
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (15 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 16/49] qapi: rename QAPISchemaEnumType.values to .members Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-06-22 12:24 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 18/49] tests: modify visit_enum_type() in test-qapi to print members Marc-André Lureau
` (36 subsequent siblings)
53 siblings, 1 reply; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
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/common.py | 12 ++++++------
scripts/qapi/events.py | 2 +-
scripts/qapi/introspect.py | 3 ++-
tests/qapi-schema/test-qapi.py | 2 +-
4 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index ea5cdfe3be..4d19146064 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -1198,7 +1198,7 @@ class QAPISchemaEnumType(QAPISchemaType):
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):
@@ -2007,11 +2007,11 @@ const QEnumLookup %(c_name)s_lookup = {
''',
c_name=c_name(name))
for m in members:
- index = c_enum_const(name, m, prefix)
+ index = c_enum_const(name, m.name, prefix)
ret += mcgen('''
- [%(index)s] = "%(value)s",
+ [%(index)s] = "%(name)s",
''',
- index=index, value=m)
+ index=index, name=m.name)
ret += mcgen('''
},
@@ -2024,7 +2024,7 @@ const QEnumLookup %(c_name)s_lookup = {
def gen_enum(name, members, prefix=None):
# append automatically generated _MAX value
- enum_members = members + ['_MAX']
+ enum_members = members + [QAPISchemaMember('_MAX')]
ret = mcgen('''
@@ -2036,7 +2036,7 @@ typedef enum %(c_name)s {
ret += mcgen('''
%(c_enum)s,
''',
- c_enum=c_enum_const(name, m, prefix))
+ c_enum=c_enum_const(name, m.name, prefix))
ret += mcgen('''
} %(c_name)s;
diff --git a/scripts/qapi/events.py b/scripts/qapi/events.py
index dae03e3d88..233c27a6c8 100644
--- a/scripts/qapi/events.py
+++ b/scripts/qapi/events.py
@@ -188,7 +188,7 @@ class QAPISchemaGenEventVisitor(QAPISchemaModularCVisitor):
with ifcontext(ifcond, self._genh, self._genc):
self._genh.add(gen_event_send_decl(name, arg_type, boxed))
self._genc.add(gen_event_send(name, arg_type, boxed, self._enum_name))
- self._event_names.append(name)
+ self._event_names.append(QAPISchemaMember(name))
def gen_events(schema, output_dir, prefix):
diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index 66f7fd00a9..d62fca84de 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -164,7 +164,8 @@ const QLitObject %(c_name)s = %(c_string)s;
self._gen_qlit(name, 'builtin', {'json-type': json_type}, [])
def visit_enum_type(self, name, info, ifcond, members, prefix):
- self._gen_qlit(name, 'enum', {'values': members}, ifcond)
+ 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/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
index f4b8feb9bc..3623deae62 100644
--- a/tests/qapi-schema/test-qapi.py
+++ b/tests/qapi-schema/test-qapi.py
@@ -24,7 +24,7 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
print('include %s' % name)
def visit_enum_type(self, name, info, ifcond, members, prefix):
- print('enum %s %s' % (name, members))
+ print('enum %s %s' % (name, [m.name for m in members]))
if prefix:
print(' prefix %s' % prefix)
self._print_if(ifcond)
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 18/49] tests: modify visit_enum_type() in test-qapi to print members
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (16 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 17/49] qapi: change enum visitor to take QAPISchemaMember Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-06-22 14:10 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 19/49] qapi: factor out check_known_keys() Marc-André Lureau
` (35 subsequent siblings)
53 siblings, 1 reply; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
Use a common self._print_members() to print enum members details.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
tests/qapi-schema/comments.out | 14 ++++++-
tests/qapi-schema/doc-bad-section.out | 13 ++++++-
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 | 18 ++++++---
12 files changed, 158 insertions(+), 31 deletions(-)
diff --git a/tests/qapi-schema/comments.out b/tests/qapi-schema/comments.out
index 8d2f1ce8a2..d1abc4b5a1 100644
--- a/tests/qapi-schema/comments.out
+++ b/tests/qapi-schema/comments.out
@@ -1,5 +1,15 @@
object q_empty
-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
module comments.json
-enum Status ['good', 'bad', 'ugly']
+enum Status
+ member good
+ member bad
+ member ugly
diff --git a/tests/qapi-schema/doc-bad-section.out b/tests/qapi-schema/doc-bad-section.out
index cd28721568..db8014eed0 100644
--- a/tests/qapi-schema/doc-bad-section.out
+++ b/tests/qapi-schema/doc-bad-section.out
@@ -1,8 +1,17 @@
object q_empty
-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
module doc-bad-section.json
-enum Enum ['one', 'two']
+enum Enum
+ member one
+ member two
doc symbol=Enum
body=
== Produces *invalid* texinfo
diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out
index 430b5a87db..3cd5c094aa 100644
--- a/tests/qapi-schema/doc-good.out
+++ b/tests/qapi-schema/doc-good.out
@@ -1,8 +1,17 @@
object q_empty
-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
module doc-good.json
-enum Enum ['one', 'two']
+enum Enum
+ member one
+ member two
object Base
member base1: Enum optional=False
object Variant1
@@ -17,7 +26,9 @@ object q_obj_Variant1-wrapper
member data: Variant1 optional=False
object q_obj_Variant2-wrapper
member data: Variant2 optional=False
-enum SugaredUnionKind ['one', 'two']
+enum SugaredUnionKind
+ member one
+ member two
object SugaredUnion
member type: SugaredUnionKind optional=False
tag type
diff --git a/tests/qapi-schema/empty.out b/tests/qapi-schema/empty.out
index 0ec234eec4..5483cb7bc6 100644
--- a/tests/qapi-schema/empty.out
+++ b/tests/qapi-schema/empty.out
@@ -1,3 +1,10 @@
object q_empty
-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
diff --git a/tests/qapi-schema/event-case.out b/tests/qapi-schema/event-case.out
index 88c0964917..f69d4ffe4e 100644
--- a/tests/qapi-schema/event-case.out
+++ b/tests/qapi-schema/event-case.out
@@ -1,6 +1,13 @@
object q_empty
-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
module event-case.json
event oops None
boxed=False
diff --git a/tests/qapi-schema/ident-with-escape.out b/tests/qapi-schema/ident-with-escape.out
index ee3b34e623..41b90fb944 100644
--- a/tests/qapi-schema/ident-with-escape.out
+++ b/tests/qapi-schema/ident-with-escape.out
@@ -1,6 +1,13 @@
object q_empty
-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
module ident-with-escape.json
object q_obj_fooA-arg
member bar1: str optional=False
diff --git a/tests/qapi-schema/include-relpath.out b/tests/qapi-schema/include-relpath.out
index ebbabd7a18..783ccfc855 100644
--- a/tests/qapi-schema/include-relpath.out
+++ b/tests/qapi-schema/include-relpath.out
@@ -1,9 +1,19 @@
object q_empty
-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
module include-relpath.json
include include/relpath.json
module include/relpath.json
include include-relpath-sub.json
module include-relpath-sub.json
-enum Status ['good', 'bad', 'ugly']
+enum Status
+ member good
+ member bad
+ member ugly
diff --git a/tests/qapi-schema/include-repetition.out b/tests/qapi-schema/include-repetition.out
index 7235e055bc..d45977ee56 100644
--- a/tests/qapi-schema/include-repetition.out
+++ b/tests/qapi-schema/include-repetition.out
@@ -1,10 +1,20 @@
object q_empty
-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
module include-repetition.json
include comments.json
module comments.json
-enum Status ['good', 'bad', 'ugly']
+enum Status
+ member good
+ member bad
+ member ugly
module include-repetition.json
include include-repetition-sub.json
module include-repetition-sub.json
diff --git a/tests/qapi-schema/include-simple.out b/tests/qapi-schema/include-simple.out
index 006f723eeb..1afe20802a 100644
--- a/tests/qapi-schema/include-simple.out
+++ b/tests/qapi-schema/include-simple.out
@@ -1,7 +1,17 @@
object q_empty
-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
module include-simple.json
include include-simple-sub.json
module include-simple-sub.json
-enum Status ['good', 'bad', 'ugly']
+enum Status
+ member good
+ member bad
+ member ugly
diff --git a/tests/qapi-schema/indented-expr.out b/tests/qapi-schema/indented-expr.out
index a79935e8c3..e2ede80310 100644
--- a/tests/qapi-schema/indented-expr.out
+++ b/tests/qapi-schema/indented-expr.out
@@ -1,6 +1,13 @@
object q_empty
-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
module indented-expr.json
command eins None -> None
gen=True success_response=True boxed=False
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index 8fe9d7a3a8..fb89a798dd 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -1,6 +1,13 @@
object q_empty
-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
module qapi-schema-test.json
object TestStruct
member integer: int optional=False
@@ -11,19 +18,24 @@ object NestedEnumsOne
member enum2: EnumOne optional=True
member enum3: EnumOne optional=False
member enum4: EnumOne optional=True
-enum MyEnum []
+enum MyEnum
object Empty1
object Empty2
base Empty1
command user_def_cmd0 Empty2 -> Empty2
gen=True success_response=True boxed=False
-enum QEnumTwo ['value1', 'value2']
+enum QEnumTwo
prefix QENUM_TWO
+ member value1
+ member value2
object UserDefOne
base UserDefZero
member string: str optional=False
member enum1: EnumOne optional=True
-enum EnumOne ['value1', 'value2', 'value3']
+enum EnumOne
+ member value1
+ member value2
+ member value3
object UserDefZero
member integer: int optional=False
object UserDefTwoDictDict
@@ -124,7 +136,21 @@ object q_obj_sizeList-wrapper
member data: sizeList optional=False
object q_obj_anyList-wrapper
member data: anyList optional=False
-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 UserDefNativeListUnion
member type: UserDefNativeListUnionKind optional=False
tag type
@@ -197,7 +223,8 @@ event EVENT_E UserDefZero
boxed=True
event EVENT_F UserDefAlternate
boxed=True
-enum __org.qemu_x-Enum ['__org.qemu_x-value']
+enum __org.qemu_x-Enum
+ member __org.qemu_x-value
object __org.qemu_x-Base
member __org.qemu_x-member1: __org.qemu_x-Enum optional=False
object __org.qemu_x-Struct
@@ -206,7 +233,8 @@ object __org.qemu_x-Struct
member wchar-t: int optional=True
object q_obj_str-wrapper
member data: str optional=False
-enum __org.qemu_x-Union1Kind ['__org.qemu_x-branch']
+enum __org.qemu_x-Union1Kind
+ member __org.qemu_x-branch
object __org.qemu_x-Union1
member type: __org.qemu_x-Union1Kind optional=False
tag type
@@ -233,11 +261,14 @@ command __org.qemu_x-command q_obj___org.qemu_x-command-arg -> __org.qemu_x-Unio
object TestIfStruct
member foo: int optional=False
if ['defined(TEST_IF_STRUCT)']
-enum TestIfEnum ['foo', 'bar']
+enum TestIfEnum
+ member foo
+ member bar
if ['defined(TEST_IF_ENUM)']
object q_obj_TestStruct-wrapper
member data: TestStruct optional=False
-enum TestIfUnionKind ['foo']
+enum TestIfUnionKind
+ member foo
if ['defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)']
object TestIfUnion
member type: TestIfUnionKind optional=False
diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
index 3623deae62..7e7b8f9f0f 100644
--- a/tests/qapi-schema/test-qapi.py
+++ b/tests/qapi-schema/test-qapi.py
@@ -12,7 +12,8 @@
from __future__ import print_function
import sys
-from qapi.common import QAPIError, QAPISchema, QAPISchemaVisitor
+from qapi.common import QAPIError, QAPISchema, QAPISchemaVisitor, \
+ QAPISchemaObjectTypeMember
class QAPISchemaTestVisitor(QAPISchemaVisitor):
@@ -24,18 +25,17 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
print('include %s' % name)
def visit_enum_type(self, name, info, ifcond, members, prefix):
- print('enum %s %s' % (name, [m.name for m in members]))
+ 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)
@@ -57,6 +57,14 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
print(' boxed=%s' % boxed)
self._print_if(ifcond)
+ @staticmethod
+ def _print_members(members):
+ for m in members:
+ print(' member %s%s' % (
+ m.name,
+ ': %s optional=%s' % (m.type.name, m.optional)
+ if isinstance(m, QAPISchemaObjectTypeMember) else ''))
+
@staticmethod
def _print_variants(variants):
if variants:
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 19/49] qapi: factor out check_known_keys()
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (17 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 18/49] tests: modify visit_enum_type() in test-qapi to print members Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-06-25 14:10 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 20/49] qapi: add a dictionnary form with 'name' key for enum members Marc-André Lureau
` (34 subsequent siblings)
53 siblings, 1 reply; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
The following patches are going to need similar checks from various
code path. This refactoring will report all conflicting keys (instead
of the first one encountered).
Modify unknown-expr-key to check plural form.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi/common.py | 27 ++++++++++++++++++-------
tests/qapi-schema/alternate-base.err | 2 +-
tests/qapi-schema/double-type.err | 2 +-
tests/qapi-schema/enum-missing-data.err | 2 +-
tests/qapi-schema/unknown-expr-key.err | 2 +-
tests/qapi-schema/unknown-expr-key.json | 2 +-
6 files changed, 25 insertions(+), 12 deletions(-)
diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index 4d19146064..fdbb5f1823 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -879,6 +879,24 @@ def check_struct(expr, info):
allow_metas=['struct'])
+def check_known_keys(info, source, keys, required, optional):
+
+ def pprint(elems):
+ return ', '.join("'" + e + "'" for e in sorted(elems))
+
+ missing = set(required) - set(keys)
+ if missing:
+ raise QAPISemError(info, "%s must have %s key%s"
+ % (source, pprint(missing),
+ 's' if len(missing) > 1 else ''))
+ allowed = set(required + optional)
+ unknown = set(keys) - allowed
+ if unknown:
+ raise QAPISemError(info, "%s has unknown key%s %s (allowed: %s)"
+ % (source, 's' if len(unknown) > 1 else '',
+ pprint(unknown), pprint(allowed)))
+
+
def check_keys(expr_elem, meta, required, optional=[]):
expr = expr_elem['expr']
info = expr_elem['info']
@@ -886,10 +904,9 @@ def check_keys(expr_elem, meta, required, optional=[]):
if not isinstance(name, str):
raise QAPISemError(info, "'%s' key must have a string value" % meta)
required = required + [meta]
+ source = "%s '%s'" % (meta, name)
+ check_known_keys(info, source, expr, required, optional)
for (key, value) in expr.items():
- if key not in required and key not in optional:
- raise QAPISemError(info, "Unknown key '%s' in %s '%s'"
- % (key, meta, name))
if (key == 'gen' or key == 'success-response') and value is not False:
raise QAPISemError(info,
"'%s' of %s '%s' should only use false value"
@@ -900,10 +917,6 @@ def check_keys(expr_elem, meta, required, optional=[]):
% (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'"
- % (key, meta, name))
def check_exprs(exprs):
diff --git a/tests/qapi-schema/alternate-base.err b/tests/qapi-schema/alternate-base.err
index 30d8a34373..2b09c4c7a3 100644
--- a/tests/qapi-schema/alternate-base.err
+++ b/tests/qapi-schema/alternate-base.err
@@ -1 +1 @@
-tests/qapi-schema/alternate-base.json:4: Unknown key 'base' in alternate 'Alt'
+tests/qapi-schema/alternate-base.json:4: alternate 'Alt' has unknown key 'base' (allowed: 'alternate', 'data', 'if')
diff --git a/tests/qapi-schema/double-type.err b/tests/qapi-schema/double-type.err
index f9613c6d6b..a8c5637659 100644
--- a/tests/qapi-schema/double-type.err
+++ b/tests/qapi-schema/double-type.err
@@ -1 +1 @@
-tests/qapi-schema/double-type.json:2: Unknown key 'command' in struct 'bar'
+tests/qapi-schema/double-type.json:2: struct 'bar' has unknown key 'command' (allowed: 'base', 'data', 'if', 'struct')
diff --git a/tests/qapi-schema/enum-missing-data.err b/tests/qapi-schema/enum-missing-data.err
index ba4873ae69..68e286badc 100644
--- a/tests/qapi-schema/enum-missing-data.err
+++ b/tests/qapi-schema/enum-missing-data.err
@@ -1 +1 @@
-tests/qapi-schema/enum-missing-data.json:2: Key 'data' is missing from enum 'MyEnum'
+tests/qapi-schema/enum-missing-data.json:2: enum 'MyEnum' must have 'data' key
diff --git a/tests/qapi-schema/unknown-expr-key.err b/tests/qapi-schema/unknown-expr-key.err
index 12f5ed5b43..d9f4e41cac 100644
--- a/tests/qapi-schema/unknown-expr-key.err
+++ b/tests/qapi-schema/unknown-expr-key.err
@@ -1 +1 @@
-tests/qapi-schema/unknown-expr-key.json:2: Unknown key 'bogus' in struct 'bar'
+tests/qapi-schema/unknown-expr-key.json:2: struct 'bar' has unknown keys 'bogus', 'foo' (allowed: 'base', 'data', 'if', 'struct')
diff --git a/tests/qapi-schema/unknown-expr-key.json b/tests/qapi-schema/unknown-expr-key.json
index 3b2be00cc4..5bcb8efd1d 100644
--- a/tests/qapi-schema/unknown-expr-key.json
+++ b/tests/qapi-schema/unknown-expr-key.json
@@ -1,2 +1,2 @@
# we reject an expression with unknown top-level keys
-{ 'struct': 'bar', 'data': { 'string': 'str'}, 'bogus': { } }
+{ 'struct': 'bar', 'data': { 'string': 'str'}, 'bogus': { }, 'foo': { } }
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 20/49] qapi: add a dictionnary form with 'name' key for enum members
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (18 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 19/49] qapi: factor out check_known_keys() Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 21/49] qapi: add 'if' to " Marc-André Lureau
` (33 subsequent siblings)
53 siblings, 0 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
Desugar the enum NAME form to { 'name': NAME }. This will allow to add
new enum members, such as 'if' in the following patch.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi/common.py | 49 ++++++++++++++++---
tests/Makefile.include | 3 +-
tests/qapi-schema/enum-bad-member.err | 1 +
...-dict-member.exit => enum-bad-member.exit} | 0
tests/qapi-schema/enum-bad-member.json | 2 +
...um-dict-member.out => enum-bad-member.out} | 0
.../qapi-schema/enum-dict-member-unknown.err | 1 +
.../qapi-schema/enum-dict-member-unknown.exit | 1 +
.../qapi-schema/enum-dict-member-unknown.json | 2 +
.../qapi-schema/enum-dict-member-unknown.out | 0
tests/qapi-schema/enum-dict-member.err | 1 -
tests/qapi-schema/enum-dict-member.json | 2 -
tests/qapi-schema/enum-missing-data.err | 2 +-
13 files changed, 51 insertions(+), 13 deletions(-)
create mode 100644 tests/qapi-schema/enum-bad-member.err
rename tests/qapi-schema/{enum-dict-member.exit => enum-bad-member.exit} (100%)
create mode 100644 tests/qapi-schema/enum-bad-member.json
rename tests/qapi-schema/{enum-dict-member.out => enum-bad-member.out} (100%)
create mode 100644 tests/qapi-schema/enum-dict-member-unknown.err
create mode 100644 tests/qapi-schema/enum-dict-member-unknown.exit
create mode 100644 tests/qapi-schema/enum-dict-member-unknown.json
create mode 100644 tests/qapi-schema/enum-dict-member-unknown.out
delete mode 100644 tests/qapi-schema/enum-dict-member.err
delete mode 100644 tests/qapi-schema/enum-dict-member.json
diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index fdbb5f1823..6aece364f1 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -739,6 +739,10 @@ def check_event(expr, info):
allow_metas=meta)
+def enum_get_names(expr):
+ return [e['name'] for e in expr['data']]
+
+
def check_union(expr, info):
name = expr['union']
base = expr.get('base')
@@ -798,7 +802,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_names(enum_define):
raise QAPISemError(info,
"Discriminator value '%s' is not found in "
"enum '%s'"
@@ -806,7 +810,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_names(enum_define):
if value not in members.keys():
raise QAPISemError(info, "Union '%s' data missing '%s' branch"
% (name, value))
@@ -837,10 +841,10 @@ 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_names(enum_expr):
if v in ['on', 'off']:
conflicting.add('QTYPE_QBOOL')
- if re.match(r'[-+0-9.]', v): # lazy, could be tightened
+ if re.match(r'[-+0-9.]', v): # lazy, could be tightened
conflicting.add('QTYPE_QNUM')
else:
conflicting.add('QTYPE_QNUM')
@@ -853,19 +857,34 @@ def check_alternate(expr, info):
types_seen[qt] = key
-def check_enum(expr, info):
+def normalize_enum(expr, info):
name = expr['enum']
members = expr.get('data')
- prefix = expr.get('prefix')
if not isinstance(members, list):
raise QAPISemError(info,
"Enum '%s' requires an array for 'data'" % name)
+
+ # translate short member form to dict form
+ for i, member in enumerate(members):
+ if not isinstance(member, dict):
+ member = {'name': member}
+ members[i] = member
+
+
+def check_enum(expr, info):
+ name = expr['enum']
+ members = expr.get('data')
+ prefix = expr.get('prefix')
+
if prefix is not None and not isinstance(prefix, str):
raise QAPISemError(info,
"Enum '%s' requires a string for 'prefix'" % name)
+
for member in members:
- check_name(info, "Member of enum '%s'" % name, member,
+ source = "Dictionary member of enum '%s'" % name
+ check_known_keys(info, source, member, ['name'], [])
+ check_name(info, "Member of enum '%s'" % name, member['name'],
enum_member=True)
@@ -926,6 +945,13 @@ def check_exprs(exprs):
for builtin in builtin_types.keys():
all_names[builtin] = 'built-in'
+ # Normalize exprs
+ for expr_elem in exprs:
+ expr = expr_elem['expr']
+ info = expr_elem['info']
+ if 'enum' in expr:
+ normalize_enum(expr, info)
+
# Learn the types and check for valid expression keys
for expr_elem in exprs:
expr = expr_elem['expr']
@@ -1631,7 +1657,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:
+ if isinstance(v, dict):
+ name = v['name']
+ else:
+ name = v
+ enum.append(QAPISchemaMember(name))
+ 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 f77ad2ba3b..444c3fd33e 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -476,10 +476,11 @@ qapi-schema += double-data.json
qapi-schema += double-type.json
qapi-schema += duplicate-key.json
qapi-schema += empty.json
+qapi-schema += enum-bad-member.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-dict-member-unknown.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-bad-member.err b/tests/qapi-schema/enum-bad-member.err
new file mode 100644
index 0000000000..211db9e6fc
--- /dev/null
+++ b/tests/qapi-schema/enum-bad-member.err
@@ -0,0 +1 @@
+tests/qapi-schema/enum-bad-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-bad-member.exit
similarity index 100%
rename from tests/qapi-schema/enum-dict-member.exit
rename to tests/qapi-schema/enum-bad-member.exit
diff --git a/tests/qapi-schema/enum-bad-member.json b/tests/qapi-schema/enum-bad-member.json
new file mode 100644
index 0000000000..98da6828b4
--- /dev/null
+++ b/tests/qapi-schema/enum-bad-member.json
@@ -0,0 +1,2 @@
+# we reject any enum member that is not a string
+{ 'enum': 'MyEnum', 'data': [ [ ] ] }
diff --git a/tests/qapi-schema/enum-dict-member.out b/tests/qapi-schema/enum-bad-member.out
similarity index 100%
rename from tests/qapi-schema/enum-dict-member.out
rename to tests/qapi-schema/enum-bad-member.out
diff --git a/tests/qapi-schema/enum-dict-member-unknown.err b/tests/qapi-schema/enum-dict-member-unknown.err
new file mode 100644
index 0000000000..7ed48beb2e
--- /dev/null
+++ b/tests/qapi-schema/enum-dict-member-unknown.err
@@ -0,0 +1 @@
+tests/qapi-schema/enum-dict-member-unknown.json:2: Dictionary member of enum 'MyEnum' has unknown key 'bad-key' (allowed: 'name')
diff --git a/tests/qapi-schema/enum-dict-member-unknown.exit b/tests/qapi-schema/enum-dict-member-unknown.exit
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/tests/qapi-schema/enum-dict-member-unknown.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/enum-dict-member-unknown.json b/tests/qapi-schema/enum-dict-member-unknown.json
new file mode 100644
index 0000000000..6664c59201
--- /dev/null
+++ b/tests/qapi-schema/enum-dict-member-unknown.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-unknown.out b/tests/qapi-schema/enum-dict-member-unknown.out
new file mode 100644
index 0000000000..e69de29bb2
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.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-missing-data.err b/tests/qapi-schema/enum-missing-data.err
index 68e286badc..b8ccae071b 100644
--- a/tests/qapi-schema/enum-missing-data.err
+++ b/tests/qapi-schema/enum-missing-data.err
@@ -1 +1 @@
-tests/qapi-schema/enum-missing-data.json:2: enum 'MyEnum' must have 'data' key
+tests/qapi-schema/enum-missing-data.json:2: Enum 'MyEnum' requires an array for 'data'
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 21/49] qapi: add 'if' to enum members
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (19 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 20/49] qapi: add a dictionnary form with 'name' key for enum members Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 22/49] qapi-event: add 'if' condition to implicit event enum Marc-André Lureau
` (32 subsequent siblings)
53 siblings, 0 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
QAPISchemaMember gains .ifcond for enum members: inherited classes,
such as QAPISchemaObjectTypeMember, will thus have an ifcond member
after this (those different types will also use the .ifcond to store
the condition and generate conditional code in the following patches).
Generated code is not changed by this patch, but with "qapi: add #if
conditions to generated code" patch.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi/common.py | 10 +++++++---
tests/Makefile.include | 1 +
tests/qapi-schema/enum-dict-member-unknown.err | 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/qapi-schema-test.json | 5 +++--
tests/qapi-schema/qapi-schema-test.out | 2 ++
tests/qapi-schema/test-qapi.py | 1 +
10 files changed, 20 insertions(+), 6 deletions(-)
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/scripts/qapi/common.py b/scripts/qapi/common.py
index 6aece364f1..22ea286191 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -883,7 +883,8 @@ def check_enum(expr, info):
for member in members:
source = "Dictionary member of enum '%s'" % name
- check_known_keys(info, source, member, ['name'], [])
+ check_known_keys(info, source, member, ['name'], ['if'])
+ check_if(member, info)
check_name(info, "Member of enum '%s'" % name, member['name'],
enum_member=True)
@@ -1362,9 +1363,10 @@ class QAPISchemaObjectType(QAPISchemaType):
class QAPISchemaMember(object):
role = 'member'
- def __init__(self, name):
+ def __init__(self, name, ifcond=None):
assert isinstance(name, str)
self.name = name
+ self.ifcond = listify_cond(ifcond)
self.owner = None
def set_owner(self, name):
@@ -1661,9 +1663,11 @@ class QAPISchema(object):
for v in values:
if isinstance(v, dict):
name = v['name']
+ ifcond = v.get('if')
else:
name = v
- enum.append(QAPISchemaMember(name))
+ ifcond = None
+ enum.append(QAPISchemaMember(name, ifcond))
return enum
def _make_implicit_enum_type(self, name, info, ifcond, values):
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 444c3fd33e..19873ea887 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -481,6 +481,7 @@ qapi-schema += enum-bad-name.json
qapi-schema += enum-bad-prefix.json
qapi-schema += enum-clash-member.json
qapi-schema += enum-dict-member-unknown.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-unknown.err b/tests/qapi-schema/enum-dict-member-unknown.err
index 7ed48beb2e..3699c89167 100644
--- a/tests/qapi-schema/enum-dict-member-unknown.err
+++ b/tests/qapi-schema/enum-dict-member-unknown.err
@@ -1 +1 @@
-tests/qapi-schema/enum-dict-member-unknown.json:2: Dictionary member of enum 'MyEnum' has unknown key 'bad-key' (allowed: 'name')
+tests/qapi-schema/enum-dict-member-unknown.json:2: Dictionary member of enum 'MyEnum' has unknown key 'bad-key' (allowed: 'if', 'name')
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
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index b997b2d43d..6a1d3b6337 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 fb89a798dd..bcef80efeb 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -264,6 +264,7 @@ object TestIfStruct
enum TestIfEnum
member foo
member bar
+ if ['defined(TEST_IF_ENUM_BAR)']
if ['defined(TEST_IF_ENUM)']
object q_obj_TestStruct-wrapper
member data: TestStruct optional=False
@@ -282,6 +283,7 @@ alternate TestIfAlternate
if ['defined(TEST_IF_ALT) && defined(TEST_IF_STRUCT)']
object q_obj_TestIfCmd-arg
member foo: TestIfStruct optional=False
+ member bar: TestIfEnum optional=False
if ['defined(TEST_IF_CMD)', 'defined(TEST_IF_STRUCT)']
command TestIfCmd q_obj_TestIfCmd-arg -> None
gen=True success_response=True boxed=False
diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
index 7e7b8f9f0f..9582742f90 100644
--- a/tests/qapi-schema/test-qapi.py
+++ b/tests/qapi-schema/test-qapi.py
@@ -64,6 +64,7 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
m.name,
': %s optional=%s' % (m.type.name, m.optional)
if isinstance(m, QAPISchemaObjectTypeMember) else ''))
+ QAPISchemaTestVisitor._print_if(m.ifcond, 8)
@staticmethod
def _print_variants(variants):
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 22/49] qapi-event: add 'if' condition to implicit event enum
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (20 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 21/49] qapi: add 'if' to " Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 23/49] qapi: rename allow_dict to allow_implicit Marc-André Lureau
` (31 subsequent siblings)
53 siblings, 0 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
Add condition to QAPIEvent enum members based on the event 'if'.
Generated code is not changed by this patch, but with "qapi: add #if
conditions to generated code" patch.
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.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi/events.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/qapi/events.py b/scripts/qapi/events.py
index 233c27a6c8..f02b65cf5a 100644
--- a/scripts/qapi/events.py
+++ b/scripts/qapi/events.py
@@ -188,7 +188,7 @@ class QAPISchemaGenEventVisitor(QAPISchemaModularCVisitor):
with ifcontext(ifcond, self._genh, self._genc):
self._genh.add(gen_event_send_decl(name, arg_type, boxed))
self._genc.add(gen_event_send(name, arg_type, boxed, self._enum_name))
- self._event_names.append(QAPISchemaMember(name))
+ self._event_names.append(QAPISchemaMember(name, ifcond))
def gen_events(schema, output_dir, prefix):
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 23/49] qapi: rename allow_dict to allow_implicit
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (21 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 22/49] qapi-event: add 'if' condition to implicit event enum Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 24/49] qapi: add a dictionary form with 'type' key for members Marc-André Lureau
` (30 subsequent siblings)
53 siblings, 0 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
This makes it a bit clearer what is the intent of the dictionnary for
the check_type() function, since there was some confusion on a
previous iteration of this series.
Suggested-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi/common.py | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index 22ea286191..9eb2b0cc37 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -660,7 +660,7 @@ def check_if(expr, info):
def check_type(info, source, value, allow_array=False,
- allow_dict=False, allow_optional=False,
+ allow_implicit=False, allow_optional=False,
allow_metas=[]):
global all_names
@@ -687,7 +687,7 @@ def check_type(info, source, value, allow_array=False,
(source, all_names[value], value))
return
- if not allow_dict:
+ if not allow_implicit:
raise QAPISemError(info, "%s should be a type name" % source)
if not isinstance(value, OrderedDict):
@@ -717,7 +717,7 @@ def check_command(expr, info):
if boxed:
args_meta += ['union', 'alternate']
check_type(info, "'data' for command '%s'" % name,
- expr.get('data'), allow_dict=not boxed, allow_optional=True,
+ expr.get('data'), allow_implicit=not boxed, allow_optional=True,
allow_metas=args_meta)
returns_meta = ['union', 'struct']
if name in returns_whitelist:
@@ -735,7 +735,7 @@ def check_event(expr, info):
if boxed:
meta += ['union', 'alternate']
check_type(info, "'data' for event '%s'" % name,
- expr.get('data'), allow_dict=not boxed, allow_optional=True,
+ expr.get('data'), allow_implicit=not boxed, allow_optional=True,
allow_metas=meta)
@@ -763,7 +763,7 @@ def check_union(expr, info):
else:
# The object must have a string or dictionary 'base'.
check_type(info, "'base' for union '%s'" % name,
- base, allow_dict=True, allow_optional=True,
+ base, allow_implicit=True, allow_optional=True,
allow_metas=['struct'])
if not base:
raise QAPISemError(info, "Flat union '%s' must have a base"
@@ -894,7 +894,7 @@ def check_struct(expr, info):
members = expr['data']
check_type(info, "'data' for struct '%s'" % name, members,
- allow_dict=True, allow_optional=True)
+ allow_implicit=True, allow_optional=True)
check_type(info, "'base' for struct '%s'" % name, expr.get('base'),
allow_metas=['struct'])
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 24/49] qapi: add a dictionary form with 'type' key for members
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (22 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 23/49] qapi: rename allow_dict to allow_implicit Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-06-20 11:13 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 25/49] qapi: add 'if' to implicit struct members Marc-André Lureau
` (29 subsequent siblings)
53 siblings, 1 reply; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
Wherever a struct/union/alternate/command/event member with NAME: TYPE
form is accepted, desugar it to a NAME: { 'type': TYPE } form.
This will allow to add new member details, such as 'if' in the
following patch to introduce conditionals, or 'default' for default
values etc.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi/common.py | 57 ++++++++++++-------
tests/Makefile.include | 3 +
tests/qapi-schema/alternate-invalid-dict.err | 1 +
tests/qapi-schema/alternate-invalid-dict.exit | 1 +
tests/qapi-schema/alternate-invalid-dict.json | 4 ++
tests/qapi-schema/alternate-invalid-dict.out | 0
tests/qapi-schema/event-nest-struct.err | 2 +-
tests/qapi-schema/flat-union-inline.err | 2 +-
tests/qapi-schema/nested-struct-data.err | 2 +-
tests/qapi-schema/qapi-schema-test.json | 10 ++--
.../struct-member-invalid-dict.err | 1 +
.../struct-member-invalid-dict.exit | 1 +
.../struct-member-invalid-dict.json | 3 +
.../struct-member-invalid-dict.out | 0
.../qapi-schema/union-branch-invalid-dict.err | 1 +
.../union-branch-invalid-dict.exit | 1 +
.../union-branch-invalid-dict.json | 4 ++
.../qapi-schema/union-branch-invalid-dict.out | 0
18 files changed, 66 insertions(+), 27 deletions(-)
create mode 100644 tests/qapi-schema/alternate-invalid-dict.err
create mode 100644 tests/qapi-schema/alternate-invalid-dict.exit
create mode 100644 tests/qapi-schema/alternate-invalid-dict.json
create mode 100644 tests/qapi-schema/alternate-invalid-dict.out
create mode 100644 tests/qapi-schema/struct-member-invalid-dict.err
create mode 100644 tests/qapi-schema/struct-member-invalid-dict.exit
create mode 100644 tests/qapi-schema/struct-member-invalid-dict.json
create mode 100644 tests/qapi-schema/struct-member-invalid-dict.out
create mode 100644 tests/qapi-schema/union-branch-invalid-dict.err
create mode 100644 tests/qapi-schema/union-branch-invalid-dict.exit
create mode 100644 tests/qapi-schema/union-branch-invalid-dict.json
create mode 100644 tests/qapi-schema/union-branch-invalid-dict.out
diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index 9eb2b0cc37..3f46ed5530 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -587,11 +587,11 @@ def discriminator_find_enum_define(expr):
if not base_members:
return None
- discriminator_type = base_members.get(discriminator)
- if not discriminator_type:
+ discriminator_member = base_members.get(discriminator)
+ if not discriminator_member:
return None
- return enum_types.get(discriminator_type)
+ return enum_types.get(discriminator_member['type'])
# Names must be letters, numbers, -, and _. They must start with letter,
@@ -659,6 +659,15 @@ def check_if(expr, info):
check_if_str(ifcond, info)
+def normalize_members(expr, field):
+ members = expr.get(field)
+ if isinstance(members, OrderedDict):
+ for key, arg in members.items():
+ if isinstance(arg, dict):
+ continue
+ members[key] = {'type': arg}
+
+
def check_type(info, source, value, allow_array=False,
allow_implicit=False, allow_optional=False,
allow_metas=[]):
@@ -703,8 +712,9 @@ def check_type(info, source, value, allow_array=False,
% (source, key))
# Todo: allow dictionaries to represent default values of
# an optional argument.
- check_type(info, "Member '%s' of %s" % (key, source), arg,
- allow_array=True,
+ member_source = "Member '%s' of %s" % (key, source)
+ check_known_keys(info, member_source, arg, ['type'], [])
+ check_type(info, member_source, arg['type'], allow_array=True,
allow_metas=['built-in', 'union', 'alternate', 'struct',
'enum'])
@@ -775,13 +785,13 @@ def check_union(expr, info):
# member of the base struct.
check_name(info, "Discriminator of flat union '%s'" % name,
discriminator)
- discriminator_type = base_members.get(discriminator)
- if not discriminator_type:
+ discriminator_member = base_members.get(discriminator)
+ if not discriminator_member:
raise QAPISemError(info,
"Discriminator '%s' is not a member of base "
"struct '%s'"
% (discriminator, base))
- enum_define = enum_types.get(discriminator_type)
+ enum_define = enum_types.get(discriminator_member['type'])
allow_metas = ['struct']
# Do not allow string discriminator
if not enum_define:
@@ -793,11 +803,14 @@ def check_union(expr, info):
if len(members) == 0:
raise QAPISemError(info, "Union '%s' cannot have empty 'data'" % name)
for (key, value) in members.items():
- check_name(info, "Member of union '%s'" % name, key)
+ source = "Member of union '%s'" % name
+ check_name(info, source, key)
+ check_known_keys(info, source, value, ['type'], [])
+ typ = value['type']
# Each value must name a known type
check_type(info, "Member '%s' of union '%s'" % (key, name),
- value, allow_array=not base, allow_metas=allow_metas)
+ typ, allow_array=not base, allow_metas=allow_metas)
# If the discriminator names an enum type, then all members
# of 'data' must also be members of the enum type.
@@ -828,18 +841,20 @@ def check_alternate(expr, info):
"in 'data'" % name)
for (key, value) in members.items():
check_name(info, "Member of alternate '%s'" % name, key)
+ source = "Member '%s' of alternate '%s'" % (key, name)
+ check_known_keys(info, source, value, ['type'], [])
+ typ = value['type']
# Ensure alternates have no type conflicts.
- check_type(info, "Member '%s' of alternate '%s'" % (key, name),
- value,
+ check_type(info, source, typ,
allow_metas=['built-in', 'union', 'struct', 'enum'])
- qtype = find_alternate_member_qtype(value)
+ qtype = find_alternate_member_qtype(typ)
if not qtype:
raise QAPISemError(info, "Alternate '%s' member '%s' cannot use "
- "type '%s'" % (name, key, value))
+ "type '%s'" % (name, key, typ))
conflicting = set([qtype])
if qtype == 'QTYPE_QSTRING':
- enum_expr = enum_types.get(value)
+ enum_expr = enum_types.get(typ)
if enum_expr:
for v in enum_get_names(enum_expr):
if v in ['on', 'off']:
@@ -952,6 +967,10 @@ def check_exprs(exprs):
info = expr_elem['info']
if 'enum' in expr:
normalize_enum(expr, info)
+ elif 'union' in expr:
+ normalize_members(expr, 'base')
+ if {'union', 'alternate', 'struct', 'command', 'event'} & set(expr):
+ normalize_members(expr, 'data')
# Learn the types and check for valid expression keys
for expr_elem in exprs:
@@ -1726,7 +1745,7 @@ class QAPISchema(object):
return QAPISchemaObjectTypeMember(name, typ, optional)
def _make_members(self, data, info):
- return [self._make_member(key, value, info)
+ return [self._make_member(key, value['type'], info)
for (key, value) in data.items()]
def _def_struct_type(self, expr, info, doc):
@@ -1762,11 +1781,11 @@ class QAPISchema(object):
name, info, doc, ifcond,
'base', self._make_members(base, info))
if tag_name:
- variants = [self._make_variant(key, value)
+ variants = [self._make_variant(key, value['type'])
for (key, value) in data.items()]
members = []
else:
- variants = [self._make_simple_variant(key, value, info)
+ variants = [self._make_simple_variant(key, value['type'], info)
for (key, value) in data.items()]
typ = self._make_implicit_enum_type(name, info, ifcond,
[v.name for v in variants])
@@ -1782,7 +1801,7 @@ class QAPISchema(object):
name = expr['alternate']
data = expr['data']
ifcond = expr.get('if')
- variants = [self._make_variant(key, value)
+ variants = [self._make_variant(key, value['type'])
for (key, value) in data.items()]
tag_member = QAPISchemaObjectTypeMember('type', 'QType', False)
self._def_entity(
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 19873ea887..7a46c1620d 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -415,6 +415,7 @@ qapi-schema += alternate-conflict-string.json
qapi-schema += alternate-conflict-bool-string.json
qapi-schema += alternate-conflict-num-string.json
qapi-schema += alternate-empty.json
+qapi-schema += alternate-invalid-dict.json
qapi-schema += alternate-nested.json
qapi-schema += alternate-unknown.json
qapi-schema += args-alternate.json
@@ -556,6 +557,7 @@ 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-member-invalid-dict.json
qapi-schema += struct-member-invalid.json
qapi-schema += trailing-comma-list.json
qapi-schema += trailing-comma-object.json
@@ -567,6 +569,7 @@ qapi-schema += unicode-str.json
qapi-schema += union-base-empty.json
qapi-schema += union-base-no-discriminator.json
qapi-schema += union-branch-case.json
+qapi-schema += union-branch-invalid-dict.json
qapi-schema += union-clash-branches.json
qapi-schema += union-empty.json
qapi-schema += union-invalid-base.json
diff --git a/tests/qapi-schema/alternate-invalid-dict.err b/tests/qapi-schema/alternate-invalid-dict.err
new file mode 100644
index 0000000000..39d3b6bca5
--- /dev/null
+++ b/tests/qapi-schema/alternate-invalid-dict.err
@@ -0,0 +1 @@
+tests/qapi-schema/alternate-invalid-dict.json:2: Member 'two' of alternate 'Alt' must have 'type' key
diff --git a/tests/qapi-schema/alternate-invalid-dict.exit b/tests/qapi-schema/alternate-invalid-dict.exit
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/tests/qapi-schema/alternate-invalid-dict.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/alternate-invalid-dict.json b/tests/qapi-schema/alternate-invalid-dict.json
new file mode 100644
index 0000000000..45f2c8ebef
--- /dev/null
+++ b/tests/qapi-schema/alternate-invalid-dict.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-invalid-dict.out b/tests/qapi-schema/alternate-invalid-dict.out
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/qapi-schema/event-nest-struct.err b/tests/qapi-schema/event-nest-struct.err
index 5a42701b8f..66cd141112 100644
--- a/tests/qapi-schema/event-nest-struct.err
+++ b/tests/qapi-schema/event-nest-struct.err
@@ -1 +1 @@
-tests/qapi-schema/event-nest-struct.json:1: Member 'a' of 'data' for event 'EVENT_A' should be a type name
+tests/qapi-schema/event-nest-struct.json:1: Member 'a' of 'data' for event 'EVENT_A' must have 'type' key
diff --git a/tests/qapi-schema/flat-union-inline.err b/tests/qapi-schema/flat-union-inline.err
index 2333358d28..82d511c7ef 100644
--- a/tests/qapi-schema/flat-union-inline.err
+++ b/tests/qapi-schema/flat-union-inline.err
@@ -1 +1 @@
-tests/qapi-schema/flat-union-inline.json:7: Member 'value1' of union 'TestUnion' should be a type name
+tests/qapi-schema/flat-union-inline.json:7: Member of union 'TestUnion' must have 'type' key
diff --git a/tests/qapi-schema/nested-struct-data.err b/tests/qapi-schema/nested-struct-data.err
index da767bade2..728591fde3 100644
--- a/tests/qapi-schema/nested-struct-data.err
+++ b/tests/qapi-schema/nested-struct-data.err
@@ -1 +1 @@
-tests/qapi-schema/nested-struct-data.json:2: Member 'a' of 'data' for command 'foo' should be a type name
+tests/qapi-schema/nested-struct-data.json:2: Member 'a' of 'data' for command 'foo' must have 'type' key
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index 6a1d3b6337..71023fb277 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -11,7 +11,7 @@
'guest-sync' ] } }
{ 'struct': 'TestStruct',
- 'data': { 'integer': 'int', 'boolean': 'bool', 'string': 'str' } }
+ 'data': { 'integer': {'type': 'int'}, 'boolean': 'bool', 'string': 'str' } }
# for testing enums
{ 'struct': 'NestedEnumsOne',
@@ -74,7 +74,7 @@
{ 'union': 'UserDefFlatUnion',
'base': 'UserDefUnionBase', # intentional forward reference
'discriminator': 'enum1',
- 'data': { 'value1' : 'UserDefA',
+ 'data': { 'value1' : {'type': 'UserDefA'},
'value2' : 'UserDefB',
'value3' : 'UserDefB' } }
@@ -93,7 +93,7 @@
{ 'struct': 'WrapAlternate',
'data': { 'alt': 'UserDefAlternate' } }
{ 'alternate': 'UserDefAlternate',
- 'data': { 'udfu': 'UserDefFlatUnion', 'e': 'EnumOne', 'i': 'int',
+ 'data': { 'udfu': {'type': 'UserDefFlatUnion'}, 'e': 'EnumOne', 'i': 'int',
'n': 'null' } }
{ 'struct': 'UserDefC',
@@ -129,7 +129,7 @@
{ 'command': 'user_def_cmd', 'data': {} }
{ 'command': 'user_def_cmd1', 'data': {'ud1a': 'UserDefOne'} }
{ 'command': 'user_def_cmd2',
- 'data': {'ud1a': 'UserDefOne', '*ud1b': 'UserDefOne'},
+ 'data': {'ud1a': {'type': 'UserDefOne'}, '*ud1b': 'UserDefOne'},
'returns': 'UserDefTwo' }
# Returning a non-dictionary requires a name from the whitelist
@@ -156,7 +156,7 @@
# testing event
{ 'struct': 'EventStructOne',
- 'data': { 'struct1': 'UserDefOne', 'string': 'str', '*enum2': 'EnumOne' } }
+ 'data': { 'struct1': {'type': 'UserDefOne'}, 'string': 'str', '*enum2': 'EnumOne' } }
{ 'event': 'EVENT_A' }
{ 'event': 'EVENT_B',
diff --git a/tests/qapi-schema/struct-member-invalid-dict.err b/tests/qapi-schema/struct-member-invalid-dict.err
new file mode 100644
index 0000000000..8435a78cb4
--- /dev/null
+++ b/tests/qapi-schema/struct-member-invalid-dict.err
@@ -0,0 +1 @@
+tests/qapi-schema/struct-member-invalid-dict.json:2: Member '*a' of 'data' for struct 'foo' must have 'type' key
diff --git a/tests/qapi-schema/struct-member-invalid-dict.exit b/tests/qapi-schema/struct-member-invalid-dict.exit
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/tests/qapi-schema/struct-member-invalid-dict.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/struct-member-invalid-dict.json b/tests/qapi-schema/struct-member-invalid-dict.json
new file mode 100644
index 0000000000..ebd9733b49
--- /dev/null
+++ b/tests/qapi-schema/struct-member-invalid-dict.json
@@ -0,0 +1,3 @@
+# exploded member form must have a 'type'
+{ 'struct': 'foo',
+ 'data': { '*a': { 'case': 'foo' } } }
diff --git a/tests/qapi-schema/struct-member-invalid-dict.out b/tests/qapi-schema/struct-member-invalid-dict.out
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/qapi-schema/union-branch-invalid-dict.err b/tests/qapi-schema/union-branch-invalid-dict.err
new file mode 100644
index 0000000000..65f9999fc0
--- /dev/null
+++ b/tests/qapi-schema/union-branch-invalid-dict.err
@@ -0,0 +1 @@
+tests/qapi-schema/union-branch-invalid-dict.json:2: Member of union 'UnionInvalidBranch' must have 'type' key
diff --git a/tests/qapi-schema/union-branch-invalid-dict.exit b/tests/qapi-schema/union-branch-invalid-dict.exit
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/tests/qapi-schema/union-branch-invalid-dict.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/union-branch-invalid-dict.json b/tests/qapi-schema/union-branch-invalid-dict.json
new file mode 100644
index 0000000000..19c5d9cacd
--- /dev/null
+++ b/tests/qapi-schema/union-branch-invalid-dict.json
@@ -0,0 +1,4 @@
+# exploded member form must have a 'type'
+{ 'union': 'UnionInvalidBranch',
+ 'data': { 'integer': { 'if': 'foo'},
+ 's8': 'int8' } }
diff --git a/tests/qapi-schema/union-branch-invalid-dict.out b/tests/qapi-schema/union-branch-invalid-dict.out
new file mode 100644
index 0000000000..e69de29bb2
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 25/49] qapi: add 'if' to implicit struct members
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (23 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 24/49] qapi: add a dictionary form with 'type' key for members Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 26/49] qapi: add an error in case a discriminator is conditionnal Marc-André Lureau
` (28 subsequent siblings)
53 siblings, 0 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
Generated code is not changed by this patch, but with "qapi: add #if
conditions to generated code" patch.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi/common.py | 14 +++++++-------
tests/qapi-schema/qapi-schema-test.json | 12 +++++++++---
tests/qapi-schema/qapi-schema-test.out | 5 +++++
3 files changed, 21 insertions(+), 10 deletions(-)
diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index 3f46ed5530..bbcb417a47 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -713,7 +713,7 @@ def check_type(info, source, value, allow_array=False,
# Todo: allow dictionaries to represent default values of
# an optional argument.
member_source = "Member '%s' of %s" % (key, source)
- check_known_keys(info, member_source, arg, ['type'], [])
+ check_known_keys(info, member_source, arg, ['type'], ['if'])
check_type(info, member_source, arg['type'], allow_array=True,
allow_metas=['built-in', 'union', 'alternate', 'struct',
'enum'])
@@ -1426,8 +1426,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
@@ -1734,7 +1734,7 @@ class QAPISchema(object):
name, info, doc, ifcond,
self._make_enum_members(data), prefix))
- def _make_member(self, name, typ, info):
+ def _make_member(self, name, typ, ifcond, info):
optional = False
if name.startswith('*'):
name = name[1:]
@@ -1742,10 +1742,10 @@ class QAPISchema(object):
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['type'], info)
+ return [self._make_member(key, value['type'], value.get('if'), info)
for (key, value) in data.items()]
def _def_struct_type(self, expr, info, doc):
@@ -1766,7 +1766,7 @@ class QAPISchema(object):
typ = self._make_array_type(typ[0], info)
typ = self._make_implicit_object_type(
typ, info, None, self.lookup_type(typ),
- 'wrapper', [self._make_member('data', typ, info)])
+ 'wrapper', [self._make_member('data', typ, None, info)])
return QAPISchemaObjectTypeVariant(case, typ)
def _def_union_type(self, expr, info, doc):
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index 71023fb277..e29c9f0769 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 bcef80efeb..e1e41acd52 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -260,6 +260,8 @@ command __org.qemu_x-command q_obj___org.qemu_x-command-arg -> __org.qemu_x-Unio
gen=True success_response=True boxed=False
object TestIfStruct
member foo: int optional=False
+ member bar: int optional=False
+ if ['defined(TEST_IF_STRUCT_BAR)']
if ['defined(TEST_IF_STRUCT)']
enum TestIfEnum
member foo
@@ -284,12 +286,15 @@ alternate TestIfAlternate
object q_obj_TestIfCmd-arg
member foo: TestIfStruct optional=False
member bar: TestIfEnum optional=False
+ if ['defined(TEST_IF_CMD_BAR)']
if ['defined(TEST_IF_CMD)', '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)']
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)']
event TestIfEvent q_obj_TestIfEvent-arg
boxed=False
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 26/49] qapi: add an error in case a discriminator is conditionnal
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (24 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 25/49] qapi: add 'if' to implicit struct members Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 27/49] qapi: add 'if' on union members Marc-André Lureau
` (27 subsequent siblings)
53 siblings, 0 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
Making a discriminator conditonal doesn't make much sense. Instead,
the union could be made conditional.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi/common.py | 11 +++++++++--
tests/Makefile.include | 1 +
.../flat-union-invalid-if-discriminator.err | 1 +
.../flat-union-invalid-if-discriminator.exit | 1 +
.../flat-union-invalid-if-discriminator.json | 17 +++++++++++++++++
.../flat-union-invalid-if-discriminator.out | 0
6 files changed, 29 insertions(+), 2 deletions(-)
create mode 100644 tests/qapi-schema/flat-union-invalid-if-discriminator.err
create mode 100644 tests/qapi-schema/flat-union-invalid-if-discriminator.exit
create mode 100644 tests/qapi-schema/flat-union-invalid-if-discriminator.json
create mode 100644 tests/qapi-schema/flat-union-invalid-if-discriminator.out
diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index bbcb417a47..d75dfbf97a 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -576,7 +576,8 @@ def find_alternate_member_qtype(qapi_type):
# Return the discriminator enum define if discriminator is specified as an
# enum type, otherwise return None.
-def discriminator_find_enum_define(expr):
+def discriminator_find_enum_define(expr, info):
+ name = expr['union']
base = expr.get('base')
discriminator = expr.get('discriminator')
@@ -591,6 +592,11 @@ def discriminator_find_enum_define(expr):
if not discriminator_member:
return None
+ if discriminator_member.get('if'):
+ raise QAPISemError(info, 'The discriminator %s.%s for union %s '
+ 'must not be conditional' %
+ (base, discriminator, name))
+
return enum_types.get(discriminator_member['type'])
@@ -1024,7 +1030,8 @@ def check_exprs(exprs):
if 'include' in expr:
continue
- if 'union' in expr and not discriminator_find_enum_define(expr):
+ info = expr_elem['info']
+ if 'union' in expr and not discriminator_find_enum_define(expr, info):
name = '%sKind' % expr['union']
elif 'alternate' in expr:
name = '%sKind' % expr['alternate']
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 7a46c1620d..e7429de9df 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -505,6 +505,7 @@ qapi-schema += flat-union-inline.json
qapi-schema += flat-union-int-branch.json
qapi-schema += flat-union-invalid-branch-key.json
qapi-schema += flat-union-invalid-discriminator.json
+qapi-schema += flat-union-invalid-if-discriminator.json
qapi-schema += flat-union-no-base.json
qapi-schema += flat-union-optional-discriminator.json
qapi-schema += flat-union-string-discriminator.json
diff --git a/tests/qapi-schema/flat-union-invalid-if-discriminator.err b/tests/qapi-schema/flat-union-invalid-if-discriminator.err
new file mode 100644
index 0000000000..0c94c9860d
--- /dev/null
+++ b/tests/qapi-schema/flat-union-invalid-if-discriminator.err
@@ -0,0 +1 @@
+tests/qapi-schema/flat-union-invalid-if-discriminator.json:13: The discriminator TestBase.enum1 for union TestUnion must not be conditional
diff --git a/tests/qapi-schema/flat-union-invalid-if-discriminator.exit b/tests/qapi-schema/flat-union-invalid-if-discriminator.exit
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/tests/qapi-schema/flat-union-invalid-if-discriminator.exit
@@ -0,0 +1 @@
+1
diff --git a/tests/qapi-schema/flat-union-invalid-if-discriminator.json b/tests/qapi-schema/flat-union-invalid-if-discriminator.json
new file mode 100644
index 0000000000..618ec36396
--- /dev/null
+++ b/tests/qapi-schema/flat-union-invalid-if-discriminator.json
@@ -0,0 +1,17 @@
+{ 'enum': 'TestEnum',
+ 'data': [ 'value1', 'value2' ] }
+
+{ 'struct': 'TestBase',
+ 'data': { 'enum1': { 'type': 'TestEnum', 'if': 'FOO' } } }
+
+{ 'struct': 'TestTypeA',
+ 'data': { 'string': 'str' } }
+
+{ 'struct': 'TestTypeB',
+ 'data': { 'integer': 'int' } }
+
+{ 'union': 'TestUnion',
+ 'base': 'TestBase',
+ 'discriminator': 'enum1',
+ 'data': { 'value1': 'TestTypeA',
+ 'value2': 'TestTypeB' } }
diff --git a/tests/qapi-schema/flat-union-invalid-if-discriminator.out b/tests/qapi-schema/flat-union-invalid-if-discriminator.out
new file mode 100644
index 0000000000..e69de29bb2
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 27/49] qapi: add 'if' on union members
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (25 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 26/49] qapi: add an error in case a discriminator is conditionnal Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 28/49] qapi: add 'if' to alternate members Marc-André Lureau
` (26 subsequent siblings)
53 siblings, 0 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
Add 'if' key to union members:
{ 'union': 'TestIfUnion', 'data':
'mem': { 'type': 'str', 'if': 'COND'} }
Generated code is not changed by this patch but with "qapi: add #if
conditions to generated code".
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi/common.py | 17 +++++++++--------
tests/qapi-schema/qapi-schema-test.json | 7 ++++++-
tests/qapi-schema/qapi-schema-test.out | 10 ++++++++++
tests/qapi-schema/test-qapi.py | 1 +
4 files changed, 26 insertions(+), 9 deletions(-)
diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index d75dfbf97a..224e911085 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -811,7 +811,7 @@ def check_union(expr, info):
for (key, value) in members.items():
source = "Member of union '%s'" % name
check_name(info, source, key)
- check_known_keys(info, source, value, ['type'], [])
+ check_known_keys(info, source, value, ['type'], ['if'])
typ = value['type']
# Each value must name a known type
@@ -1492,8 +1492,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):
@@ -1767,14 +1767,14 @@ class QAPISchema(object):
def _make_variant(self, case, typ):
return QAPISchemaObjectTypeVariant(case, typ)
- def _make_simple_variant(self, case, typ, info):
+ def _make_simple_variant(self, case, typ, ifcond, info):
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),
'wrapper', [self._make_member('data', typ, None, info)])
- return QAPISchemaObjectTypeVariant(case, typ)
+ return QAPISchemaObjectTypeVariant(case, typ, ifcond)
def _def_union_type(self, expr, info, doc):
name = expr['union']
@@ -1792,10 +1792,11 @@ class QAPISchema(object):
for (key, value) in data.items()]
members = []
else:
- variants = [self._make_simple_variant(key, value['type'], info)
+ variants = [self._make_simple_variant(key, value['type'],
+ value.get('if'), info)
for (key, value) in data.items()]
- typ = self._make_implicit_enum_type(name, info, ifcond,
- [v.name for v in variants])
+ enum = [{'name': v.name, 'if': v.ifcond} for v in variants]
+ typ = self._make_implicit_enum_type(name, info, ifcond, enum)
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 e29c9f0769..b4b8a0a2cc 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 e1e41acd52..8dbcd6f24b 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -272,12 +272,22 @@ object q_obj_TestStruct-wrapper
member data: TestStruct optional=False
enum TestIfUnionKind
member foo
+ member union_bar
+ if ['defined(TEST_IF_UNION_BAR)']
if ['defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)']
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)']
+object q_obj_TestIfUnionCmd-arg
+ member union_cmd_arg: TestIfUnion optional=False
+ if ['defined(TEST_IF_UNION)']
+command TestIfUnionCmd q_obj_TestIfUnionCmd-arg -> None
+ gen=True success_response=True boxed=False
+ if ['defined(TEST_IF_UNION)']
alternate TestIfAlternate
tag type
case foo: int
diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
index 9582742f90..4dfa8651c8 100644
--- a/tests/qapi-schema/test-qapi.py
+++ b/tests/qapi-schema/test-qapi.py
@@ -72,6 +72,7 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
print(' tag %s' % variants.tag_member.name)
for v in variants.variants:
print(' case %s: %s' % (v.name, v.type.name))
+ QAPISchemaTestVisitor._print_if(v.ifcond, 8)
@staticmethod
def _print_if(ifcond, indent=4):
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 28/49] qapi: add 'if' to alternate members
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (26 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 27/49] qapi: add 'if' on union members Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 29/49] qapi: add #if conditions to generated code members Marc-André Lureau
` (25 subsequent siblings)
53 siblings, 0 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
Add 'if' key to alternate members:
{ 'alternate': 'TestIfAlternate', 'data':
{ 'alt': { 'type': 'TestStruct', 'if': 'COND' } } }
Generated code is not changed by this patch but with "qapi: add #if
conditions to generated code".
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi/common.py | 10 +++++-----
tests/qapi-schema/qapi-schema-test.json | 6 +++++-
tests/qapi-schema/qapi-schema-test.out | 9 ++++++++-
3 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index 224e911085..c913c18d2d 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -848,7 +848,7 @@ def check_alternate(expr, info):
for (key, value) in members.items():
check_name(info, "Member of alternate '%s'" % name, key)
source = "Member '%s' of alternate '%s'" % (key, name)
- check_known_keys(info, source, value, ['type'], [])
+ check_known_keys(info, source, value, ['type'], ['if'])
typ = value['type']
# Ensure alternates have no type conflicts.
@@ -1764,8 +1764,8 @@ class QAPISchema(object):
self._make_members(data, info),
None))
- def _make_variant(self, case, typ):
- return QAPISchemaObjectTypeVariant(case, typ)
+ def _make_variant(self, case, typ, ifcond):
+ return QAPISchemaObjectTypeVariant(case, typ, ifcond)
def _make_simple_variant(self, case, typ, ifcond, info):
if isinstance(typ, list):
@@ -1788,7 +1788,7 @@ class QAPISchema(object):
name, info, doc, ifcond,
'base', self._make_members(base, info))
if tag_name:
- variants = [self._make_variant(key, value['type'])
+ variants = [self._make_variant(key, value['type'], value.get('if'))
for (key, value) in data.items()]
members = []
else:
@@ -1809,7 +1809,7 @@ class QAPISchema(object):
name = expr['alternate']
data = expr['data']
ifcond = expr.get('if')
- variants = [self._make_variant(key, value['type'])
+ variants = [self._make_variant(key, value['type'], value.get('if'))
for (key, value) in data.items()]
tag_member = QAPISchemaObjectTypeMember('type', 'QType', False)
self._def_entity(
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index b4b8a0a2cc..cd33c084cb 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 8dbcd6f24b..657e487cbf 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -291,8 +291,15 @@ command TestIfUnionCmd q_obj_TestIfUnionCmd-arg -> None
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)']
+object q_obj_TestIfAlternateCmd-arg
+ member alt_cmd_arg: TestIfAlternate optional=False
+ if ['defined(TEST_IF_ALT)']
+command TestIfAlternateCmd q_obj_TestIfAlternateCmd-arg -> None
+ gen=True success_response=True boxed=False
+ if ['defined(TEST_IF_ALT)']
object q_obj_TestIfCmd-arg
member foo: TestIfStruct optional=False
member bar: TestIfEnum optional=False
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 29/49] qapi: add #if conditions to generated code members
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (27 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 28/49] qapi: add 'if' to alternate members Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 30/49] docs: document schema configuration Marc-André Lureau
` (24 subsequent siblings)
53 siblings, 0 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
Wrap generated enum/struct members and code with #if/#endif, using the
.ifcond members added in the previous patches.
Some types generate both enum and struct members for example, so a
step-by-step is unnecessarily complicated to deal with (it would
easily generate invalid intermediary code).
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi/common.py | 4 ++++
scripts/qapi/introspect.py | 13 +++++++++----
scripts/qapi/types.py | 4 ++++
scripts/qapi/visit.py | 8 +++++++-
4 files changed, 24 insertions(+), 5 deletions(-)
diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index c913c18d2d..174b39ea50 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -2084,11 +2084,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('''
},
@@ -2110,10 +2112,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;
diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index d62fca84de..5b147a3d6f 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -151,6 +151,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):
@@ -158,14 +160,16 @@ 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}, [])
def visit_enum_type(self, name, info, ifcond, members, prefix):
self._gen_qlit(name, 'enum',
- {'values': [m.name for m in members]}, ifcond)
+ {'values': [(m.name, m.ifcond) for m in members]},
+ ifcond)
def visit_array_type(self, name, info, ifcond, element_type):
element = self._use_type(element_type)
@@ -181,8 +185,9 @@ 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)}
- for m in variants.variants]}, ifcond)
+ {'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,
gen, success_response, boxed, allow_oob):
diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py
index 5b790cb41d..b0d3ddb596 100644
--- a/scripts/qapi/types.py
+++ b/scripts/qapi/types.py
@@ -43,6 +43,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;
@@ -52,6 +53,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
@@ -131,11 +133,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 ee776386ae..dc5a3173fc 100644
--- a/scripts/qapi/visit.py
+++ b/scripts/qapi/visit.py
@@ -54,6 +54,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)) {
@@ -73,6 +74,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('''
@@ -81,6 +83,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);
@@ -91,6 +94,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();
@@ -178,9 +182,10 @@ void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error
}
switch ((*obj)->type) {
''',
- c_name=c_name(name))
+ c_name=c_name(name))
for var in variants.variants:
+ ret += gen_if(var.ifcond)
ret += mcgen('''
case %(case)s:
''',
@@ -208,6 +213,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.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 30/49] docs: document schema configuration
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (28 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 29/49] qapi: add #if conditions to generated code members Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-06-22 11:10 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 31/49] qapi2texi: add 'If:' section to generated documentation Marc-André Lureau
` (23 subsequent siblings)
53 siblings, 1 reply; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
docs/devel/qapi-code-gen.txt | 38 ++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt
index a569d24745..eec52e63e5 100644
--- a/docs/devel/qapi-code-gen.txt
+++ b/docs/devel/qapi-code-gen.txt
@@ -728,6 +728,44 @@ Example: Red Hat, Inc. controls redhat.com, and may therefore add a
downstream command __com.redhat_drive-mirror.
+=== Configuring the schema ===
+
+Top-level QAPI expressions and various type expressions listed below
+can take an 'if' key. The value must be a string or a list of
+string. The corresponding generated code will then guard the inclusion
+of that member in the larger struct or function with #if IFCOND
+(or several #if lines for a list), where IFCOND is the value of the
+'if' key.
+
+'struct', 'enum', 'union', 'alternate', 'command' and 'event'
+top-level QAPI expressions can take an 'if' keyword like:
+
+{ 'struct': 'IfStruct', 'data': { 'foo': 'int' },
+ 'if': 'defined(IFCOND)' }
+
+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.
+
+{ 'struct': 'IfStruct', 'data':
+ { 'foo': 'int',
+ 'bar': { 'type': 'int', 'if': 'defined(IFCOND)'} } }
+
+An enum value can be replaced by a dictionary with a 'name' and a 'if'
+key:
+
+{ 'enum': 'IfEnum', 'data':
+ [ 'foo',
+ { 'name' : 'bar', 'if': 'defined(IFCOND)' } ] }
+
+Please note that you are responsible 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.
+
+The presence of 'if' keys in the schema is reflected through to the
+introspection output depending on the build configuration.
+
+
== Client JSON Protocol introspection ==
Clients of a Client JSON Protocol commonly need to figure out what
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 31/49] qapi2texi: add 'If:' section to generated documentation
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (29 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 30/49] docs: document schema configuration Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-06-21 16:29 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 32/49] qapi2texi: add 'If:' condition to enum values Marc-André Lureau
` (22 subsequent siblings)
53 siblings, 1 reply; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
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/qapi/doc.py | 22 ++++++++++++----------
tests/qapi-schema/doc-good.json | 2 +-
tests/qapi-schema/doc-good.out | 1 +
tests/qapi-schema/doc-good.texi | 2 ++
4 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/scripts/qapi/doc.py b/scripts/qapi/doc.py
index 6c2bf98e1d..783b13303a 100755
--- a/scripts/qapi/doc.py
+++ b/scripts/qapi/doc.py
@@ -174,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:
@@ -185,14 +185,16 @@ def texi_sections(doc):
body += texi_example(section.text)
else:
body += texi_format(section.text)
+ if ifcond:
+ body += '\n\n@b{If:} @code{%s}' % ", ".join(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.common.QAPISchemaVisitor):
@@ -208,7 +210,7 @@ class QAPISchemaGenDocVisitor(qapi.common.QAPISchemaVisitor):
doc = self.cur_doc
self._gen.add(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):
@@ -217,14 +219,14 @@ class QAPISchemaGenDocVisitor(qapi.common.QAPISchemaVisitor):
base = None
self._gen.add(TYPE_FMT(type='Object',
name=doc.symbol,
- body=texi_entity(doc, 'Members',
+ body=texi_entity(doc, 'Members', ifcond,
base, variants)))
def visit_alternate_type(self, name, info, ifcond, variants):
doc = self.cur_doc
self._gen.add(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, allow_oob):
@@ -233,9 +235,9 @@ class QAPISchemaGenDocVisitor(qapi.common.QAPISchemaVisitor):
body = texi_body(doc)
body += ('\n@b{Arguments:} the members of @code{%s}\n'
% 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._gen.add(MSG_FMT(type='Command',
name=doc.symbol,
body=body))
@@ -244,7 +246,7 @@ class QAPISchemaGenDocVisitor(qapi.common.QAPISchemaVisitor):
doc = self.cur_doc
self._gen.add(MSG_FMT(type='Event',
name=doc.symbol,
- body=texi_entity(doc, 'Arguments')))
+ body=texi_entity(doc, 'Arguments', ifcond)))
def symbol(self, doc, entity):
if self._gen._body:
@@ -257,7 +259,7 @@ class QAPISchemaGenDocVisitor(qapi.common.QAPISchemaVisitor):
assert not doc.args
if self._gen._body:
self._gen.add('\n')
- self._gen.add(texi_body(doc) + texi_sections(doc))
+ self._gen.add(texi_body(doc) + texi_sections(doc, None))
def gen_doc(schema, output_dir, prefix):
diff --git a/tests/qapi-schema/doc-good.json b/tests/qapi-schema/doc-good.json
index 97ab4625ff..984cd8ed06 100644
--- a/tests/qapi-schema/doc-good.json
+++ b/tests/qapi-schema/doc-good.json
@@ -55,7 +55,7 @@
#
# @two is undocumented
##
-{ 'enum': 'Enum', 'data': [ 'one', 'two' ] }
+{ 'enum': 'Enum', 'data': [ 'one', 'two' ], 'if': 'defined(IFCOND)' }
##
# @Base:
diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out
index 3cd5c094aa..e4054e293c 100644
--- a/tests/qapi-schema/doc-good.out
+++ b/tests/qapi-schema/doc-good.out
@@ -12,6 +12,7 @@ module doc-good.json
enum Enum
member one
member two
+ if ['defined(IFCOND)']
object Base
member base1: Enum optional=False
object Variant1
diff --git a/tests/qapi-schema/doc-good.texi b/tests/qapi-schema/doc-good.texi
index 0aed2300a5..e42eace474 100644
--- a/tests/qapi-schema/doc-good.texi
+++ b/tests/qapi-schema/doc-good.texi
@@ -89,6 +89,8 @@ Not documented
@end table
@code{two} is undocumented
+
+@b{If:} @code{defined(IFCOND)}
@end deftp
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 32/49] qapi2texi: add 'If:' condition to enum values
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (30 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 31/49] qapi2texi: add 'If:' section to generated documentation Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 33/49] qapi2texi: add 'If:' condition to struct members Marc-André Lureau
` (21 subsequent siblings)
53 siblings, 0 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi/doc.py | 5 ++++-
tests/qapi-schema/doc-good.json | 4 +++-
tests/qapi-schema/doc-good.out | 1 +
tests/qapi-schema/doc-good.texi | 2 ++
4 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/scripts/qapi/doc.py b/scripts/qapi/doc.py
index 783b13303a..f629425f53 100755
--- a/scripts/qapi/doc.py
+++ b/scripts/qapi/doc.py
@@ -128,7 +128,10 @@ 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' %
+ ', '.join(value.ifcond) if value.ifcond else '')
def texi_member(member, suffix=''):
diff --git a/tests/qapi-schema/doc-good.json b/tests/qapi-schema/doc-good.json
index 984cd8ed06..c7fe08c530 100644
--- a/tests/qapi-schema/doc-good.json
+++ b/tests/qapi-schema/doc-good.json
@@ -55,7 +55,9 @@
#
# @two is undocumented
##
-{ 'enum': 'Enum', 'data': [ 'one', 'two' ], 'if': 'defined(IFCOND)' }
+{ 'enum': 'Enum', 'data':
+ [ { 'name': 'one', 'if': 'defined(IFENUM)' }, 'two' ],
+ 'if': 'defined(IFCOND)' }
##
# @Base:
diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out
index e4054e293c..d27d345de2 100644
--- a/tests/qapi-schema/doc-good.out
+++ b/tests/qapi-schema/doc-good.out
@@ -11,6 +11,7 @@ enum QType
module doc-good.json
enum Enum
member one
+ if ['defined(IFENUM)']
member two
if ['defined(IFCOND)']
object Base
diff --git a/tests/qapi-schema/doc-good.texi b/tests/qapi-schema/doc-good.texi
index e42eace474..2446a1c702 100644
--- a/tests/qapi-schema/doc-good.texi
+++ b/tests/qapi-schema/doc-good.texi
@@ -83,6 +83,8 @@ Examples:
@b{Values:}
@table @asis
@item @code{one}
+@b{If:} @code{defined(IFENUM)}
+
The @emph{one} @{and only@}
@item @code{two}
Not documented
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 33/49] qapi2texi: add 'If:' condition to struct members
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (31 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 32/49] qapi2texi: add 'If:' condition to enum values Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 34/49] qapi2texi: add condition to variants Marc-André Lureau
` (20 subsequent siblings)
53 siblings, 0 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi/doc.py | 4 +++-
tests/qapi-schema/doc-good.json | 3 ++-
tests/qapi-schema/doc-good.out | 1 +
tests/qapi-schema/doc-good.texi | 2 ++
4 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/scripts/qapi/doc.py b/scripts/qapi/doc.py
index f629425f53..42e34e1fe3 100755
--- a/scripts/qapi/doc.py
+++ b/scripts/qapi/doc.py
@@ -138,9 +138,11 @@ 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' %
+ ', '.join(member.ifcond) if member.ifcond else '',
suffix)
diff --git a/tests/qapi-schema/doc-good.json b/tests/qapi-schema/doc-good.json
index c7fe08c530..158443b1a3 100644
--- a/tests/qapi-schema/doc-good.json
+++ b/tests/qapi-schema/doc-good.json
@@ -72,7 +72,8 @@
#
# Another paragraph (but no @var: line)
##
-{ 'struct': 'Variant1', 'data': { 'var1': 'str' } }
+{ 'struct': 'Variant1',
+ 'data': { 'var1': { 'type': 'str', 'if': 'defined(IFSTR)' } } }
##
# @Variant2:
diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out
index d27d345de2..9976d29eb0 100644
--- a/tests/qapi-schema/doc-good.out
+++ b/tests/qapi-schema/doc-good.out
@@ -18,6 +18,7 @@ object Base
member base1: Enum optional=False
object Variant1
member var1: str optional=False
+ if ['defined(IFSTR)']
object Variant2
object Object
base Base
diff --git a/tests/qapi-schema/doc-good.texi b/tests/qapi-schema/doc-good.texi
index 2446a1c702..255eed9a30 100644
--- a/tests/qapi-schema/doc-good.texi
+++ b/tests/qapi-schema/doc-good.texi
@@ -120,6 +120,8 @@ Another paragraph (but no @code{var}: line)
@b{Members:}
@table @asis
@item @code{var1: string}
+@b{If:} @code{defined(IFSTR)}
+
Not documented
@end table
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 34/49] qapi2texi: add condition to variants
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (32 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 33/49] qapi2texi: add 'If:' condition to struct members Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 35/49] qapi: add conditions to VNC type/commands/events on the schema Marc-André Lureau
` (19 subsequent siblings)
53 siblings, 0 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi/doc.py | 5 +++--
tests/qapi-schema/doc-good.json | 4 ++--
tests/qapi-schema/doc-good.out | 3 +++
tests/qapi-schema/doc-good.texi | 4 ++--
4 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/scripts/qapi/doc.py b/scripts/qapi/doc.py
index 42e34e1fe3..40dcedc6ed 100755
--- a/scripts/qapi/doc.py
+++ b/scripts/qapi/doc.py
@@ -165,8 +165,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,
+ ' (@b{If:} @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:
diff --git a/tests/qapi-schema/doc-good.json b/tests/qapi-schema/doc-good.json
index 158443b1a3..afe46d93f0 100644
--- a/tests/qapi-schema/doc-good.json
+++ b/tests/qapi-schema/doc-good.json
@@ -86,13 +86,13 @@
{ 'union': 'Object',
'base': 'Base',
'discriminator': 'base1',
- 'data': { 'one': 'Variant1', 'two': 'Variant2' } }
+ 'data': { 'one': 'Variant1', 'two': { 'type': 'Variant2', 'if': 'IFTWO' } } }
##
# @SugaredUnion:
##
{ 'union': 'SugaredUnion',
- 'data': { 'one': 'Variant1', 'two': 'Variant2' } }
+ 'data': { 'one': 'Variant1', 'two': { 'type': 'Variant2', 'if': 'IFTWO' } } }
##
# == Another subsection
diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out
index 9976d29eb0..4b36cf6f7d 100644
--- a/tests/qapi-schema/doc-good.out
+++ b/tests/qapi-schema/doc-good.out
@@ -25,6 +25,7 @@ object Object
tag base1
case one: Variant1
case two: Variant2
+ if ['IFTWO']
object q_obj_Variant1-wrapper
member data: Variant1 optional=False
object q_obj_Variant2-wrapper
@@ -32,11 +33,13 @@ object q_obj_Variant2-wrapper
enum SugaredUnionKind
member one
member two
+ if ['IFTWO']
object SugaredUnion
member type: SugaredUnionKind optional=False
tag type
case one: q_obj_Variant1-wrapper
case two: q_obj_Variant2-wrapper
+ if ['IFTWO']
object q_obj_cmd-arg
member arg1: int optional=False
member arg2: str optional=True
diff --git a/tests/qapi-schema/doc-good.texi b/tests/qapi-schema/doc-good.texi
index 255eed9a30..6e226a6231 100644
--- a/tests/qapi-schema/doc-good.texi
+++ b/tests/qapi-schema/doc-good.texi
@@ -145,7 +145,7 @@ Not documented
@table @asis
@item The members of @code{Base}
@item The members of @code{Variant1} when @code{base1} is @t{"one"}
-@item The members of @code{Variant2} when @code{base1} is @t{"two"}
+@item The members of @code{Variant2} when @code{base1} is @t{"two"} (@b{If:} @code{['IFTWO']})
@end table
@end deftp
@@ -161,7 +161,7 @@ Not documented
@item @code{type}
One of @t{"one"}, @t{"two"}
@item @code{data: Variant1} when @code{type} is @t{"one"}
-@item @code{data: Variant2} when @code{type} is @t{"two"}
+@item @code{data: Variant2} when @code{type} is @t{"two"} (@b{If:} @code{['IFTWO']})
@end table
@end deftp
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 35/49] qapi: add conditions to VNC type/commands/events on the schema
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (33 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 34/49] qapi2texi: add condition to variants Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 36/49] qapi: add conditions to SPICE " Marc-André Lureau
` (18 subsequent siblings)
53 siblings, 0 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
Add #if defined(CONFIG_VNC) in generated code, and adjust the
qmp/hmp code accordingly.
query-qmp-schema no longer reports the command/events etc as
available when disabled at compile.
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
HMP change:
* info vnc
Will return "unknown command: 'info vnc'" when VNC is compiled
out (same as error for spice when --disable-spice)
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>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
---
qapi/ui.json | 45 +++++++++++++++++++++++++++-----------------
ui/vnc.h | 2 ++
hmp.c | 9 ++++++++-
qmp.c | 30 ++++-------------------------
hmp-commands-info.hx | 2 ++
5 files changed, 44 insertions(+), 44 deletions(-)
diff --git a/qapi/ui.json b/qapi/ui.json
index 5d01ad4304..4b96509446 100644
--- a/qapi/ui.json
+++ b/qapi/ui.json
@@ -377,7 +377,8 @@
'data': { 'host': 'str',
'service': 'str',
'family': 'NetworkAddressFamily',
- 'websocket': 'bool' } }
+ 'websocket': 'bool' },
+ 'if': 'defined(CONFIG_VNC)' }
##
# @VncServerInfo:
@@ -391,7 +392,8 @@
##
{ 'struct': 'VncServerInfo',
'base': 'VncBasicInfo',
- 'data': { '*auth': 'str' } }
+ 'data': { '*auth': 'str' },
+ 'if': 'defined(CONFIG_VNC)' }
##
# @VncClientInfo:
@@ -408,7 +410,8 @@
##
{ 'struct': 'VncClientInfo',
'base': 'VncBasicInfo',
- 'data': { '*x509_dname': 'str', '*sasl_username': 'str' } }
+ 'data': { '*x509_dname': 'str', '*sasl_username': 'str' },
+ 'if': 'defined(CONFIG_VNC)' }
##
# @VncInfo:
@@ -449,7 +452,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:
@@ -460,7 +464,8 @@
##
{ 'enum': 'VncPrimaryAuth',
'data': [ 'none', 'vnc', 'ra2', 'ra2ne', 'tight', 'ultra',
- 'tls', 'vencrypt', 'sasl' ] }
+ 'tls', 'vencrypt', 'sasl' ],
+ 'if': 'defined(CONFIG_VNC)' }
##
# @VncVencryptSubAuth:
@@ -474,8 +479,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:
@@ -492,8 +497,8 @@
{ 'struct': 'VncServerInfo2',
'base': 'VncBasicInfo',
'data': { 'auth' : 'VncPrimaryAuth',
- '*vencrypt' : 'VncVencryptSubAuth' } }
-
+ '*vencrypt' : 'VncVencryptSubAuth' },
+ 'if': 'defined(CONFIG_VNC)' }
##
# @VncInfo2:
@@ -525,7 +530,8 @@
'clients' : ['VncClientInfo'],
'auth' : 'VncPrimaryAuth',
'*vencrypt' : 'VncVencryptSubAuth',
- '*display' : 'str' } }
+ '*display' : 'str' },
+ 'if': 'defined(CONFIG_VNC)' }
##
# @query-vnc:
@@ -556,8 +562,8 @@
# }
#
##
-{ 'command': 'query-vnc', 'returns': 'VncInfo' }
-
+{ 'command': 'query-vnc', 'returns': 'VncInfo',
+ 'if': 'defined(CONFIG_VNC)' }
##
# @query-vnc-servers:
#
@@ -567,7 +573,8 @@
#
# Since: 2.3
##
-{ 'command': 'query-vnc-servers', 'returns': ['VncInfo2'] }
+{ 'command': 'query-vnc-servers', 'returns': ['VncInfo2'],
+ 'if': 'defined(CONFIG_VNC)' }
##
# @change-vnc-password:
@@ -581,7 +588,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:
@@ -610,7 +618,8 @@
##
{ 'event': 'VNC_CONNECTED',
'data': { 'server': 'VncServerInfo',
- 'client': 'VncBasicInfo' } }
+ 'client': 'VncBasicInfo' },
+ 'if': 'defined(CONFIG_VNC)' }
##
# @VNC_INITIALIZED:
@@ -637,7 +646,8 @@
##
{ 'event': 'VNC_INITIALIZED',
'data': { 'server': 'VncServerInfo',
- 'client': 'VncClientInfo' } }
+ 'client': 'VncClientInfo' },
+ 'if': 'defined(CONFIG_VNC)' }
##
# @VNC_DISCONNECTED:
@@ -663,7 +673,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 7b29def77d..fede2096d9 100644
--- a/ui/vnc.h
+++ b/ui/vnc.h
@@ -294,7 +294,9 @@ struct VncState
bool encode_ws;
bool websocket;
+#ifdef CONFIG_VNC
VncClientInfo *info;
+#endif
/* Job thread bottom half has put data for a forced update
* into the output buffer. This offset points to the end of
diff --git a/hmp.c b/hmp.c
index 679467d85a..352c2f56f4 100644
--- a/hmp.c
+++ b/hmp.c
@@ -596,6 +596,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)
@@ -683,6 +684,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)
@@ -1721,12 +1723,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)
{
@@ -1737,6 +1741,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,
@@ -1751,7 +1756,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 f72261667f..ee1a816a42 100644
--- a/qmp.c
+++ b/qmp.c
@@ -129,22 +129,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_unregister_commands_hack() ensures that QMP command query-spice
@@ -402,23 +386,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/hmp-commands-info.hx b/hmp-commands-info.hx
index ddfcd5adcc..7f681df119 100644
--- a/hmp-commands-info.hx
+++ b/hmp-commands-info.hx
@@ -421,6 +421,7 @@ STEXI
Show which guest mouse is receiving events.
ETEXI
+#if defined(CONFIG_VNC)
{
.name = "vnc",
.args_type = "",
@@ -428,6 +429,7 @@ ETEXI
.help = "show the vnc server status",
.cmd = hmp_info_vnc,
},
+#endif
STEXI
@item info vnc
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 36/49] qapi: add conditions to SPICE type/commands/events on the schema
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (34 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 35/49] qapi: add conditions to VNC type/commands/events on the schema Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 37/49] qapi: add conditions to REPLICATION type/commands " Marc-André Lureau
` (17 subsequent siblings)
53 siblings, 0 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
Add #if defined(CONFIG_SPICE) in generated code, and adjust the
qmp/hmp code accordingly.
query-qmp-schema no longer reports the command/events etc as
available when disabled at compile time.
Commands made conditional:
* query-spice
Before the patch, the command for !CONFIG_SPICE is unregistered. It
will fail with the same error.
Events made conditional:
* SPICE_CONNECTED, SPICE_INITIALIZED, SPICE_DISCONNECTED,
SPICE_MIGRATE_COMPLETED
Chardev made conditional:
* spiceport, spicevmc
Before and after the patch for !CONFIG_SPICE, the error is the
same ('spiceport' is not a valid char driver name).
No HMP change, the code was already conditional.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Gerd Hoffmann <kraxel@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 4b96509446..e47fae2e90 100644
--- a/qapi/ui.json
+++ b/qapi/ui.json
@@ -118,7 +118,8 @@
{ 'struct': 'SpiceBasicInfo',
'data': { 'host': 'str',
'port': 'str',
- 'family': 'NetworkAddressFamily' } }
+ 'family': 'NetworkAddressFamily' },
+ 'if': 'defined(CONFIG_SPICE)' }
##
# @SpiceServerInfo:
@@ -131,7 +132,8 @@
##
{ 'struct': 'SpiceServerInfo',
'base': 'SpiceBasicInfo',
- 'data': { '*auth': 'str' } }
+ 'data': { '*auth': 'str' },
+ 'if': 'defined(CONFIG_SPICE)' }
##
# @SpiceChannel:
@@ -156,7 +158,8 @@
{ 'struct': 'SpiceChannel',
'base': 'SpiceBasicInfo',
'data': {'connection-id': 'int', 'channel-type': 'int', 'channel-id': 'int',
- 'tls': 'bool'} }
+ 'tls': 'bool'},
+ 'if': 'defined(CONFIG_SPICE)' }
##
# @SpiceQueryMouseMode:
@@ -175,7 +178,8 @@
# Since: 1.1
##
{ 'enum': 'SpiceQueryMouseMode',
- 'data': [ 'client', 'server', 'unknown' ] }
+ 'data': [ 'client', 'server', 'unknown' ],
+ 'if': 'defined(CONFIG_SPICE)' }
##
# @SpiceInfo:
@@ -212,7 +216,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:
@@ -257,7 +262,8 @@
# }
#
##
-{ 'command': 'query-spice', 'returns': 'SpiceInfo' }
+{ 'command': 'query-spice', 'returns': 'SpiceInfo',
+ 'if': 'defined(CONFIG_SPICE)' }
##
# @SPICE_CONNECTED:
@@ -282,7 +288,8 @@
##
{ 'event': 'SPICE_CONNECTED',
'data': { 'server': 'SpiceBasicInfo',
- 'client': 'SpiceBasicInfo' } }
+ 'client': 'SpiceBasicInfo' },
+ 'if': 'defined(CONFIG_SPICE)' }
##
# @SPICE_INITIALIZED:
@@ -310,7 +317,8 @@
##
{ 'event': 'SPICE_INITIALIZED',
'data': { 'server': 'SpiceServerInfo',
- 'client': 'SpiceChannel' } }
+ 'client': 'SpiceChannel' },
+ 'if': 'defined(CONFIG_SPICE)' }
##
# @SPICE_DISCONNECTED:
@@ -335,7 +343,8 @@
##
{ 'event': 'SPICE_DISCONNECTED',
'data': { 'server': 'SpiceBasicInfo',
- 'client': 'SpiceBasicInfo' } }
+ 'client': 'SpiceBasicInfo' },
+ 'if': 'defined(CONFIG_SPICE)' }
##
# @SPICE_MIGRATE_COMPLETED:
@@ -350,7 +359,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 6ccd2fc089..8a5539579b 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1087,9 +1087,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 ee1a816a42..d8f80cb04e 100644
--- a/qmp.c
+++ b/qmp.c
@@ -129,22 +129,6 @@ void qmp_cpu_add(int64_t id, Error **errp)
}
}
-#ifndef CONFIG_SPICE
-/*
- * qmp_unregister_commands_hack() 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.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 37/49] qapi: add conditions to REPLICATION type/commands on the schema
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (35 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 36/49] qapi: add conditions to SPICE " Marc-André Lureau
@ 2018-03-21 11:51 ` Marc-André Lureau
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 38/49] build-sys: move qmp-introspect per target Marc-André Lureau
` (16 subsequent siblings)
53 siblings, 0 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:51 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
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 closer to killing qmp_unregister_commands_hack().
* enum BlockdevDriver value "replication" in command blockdev-add
* BlockdevOptions variant @replication
And related structures.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qapi/block-core.json | 13 +++++++++----
qapi/migration.json | 12 ++++++++----
migration/colo.c | 16 ++++------------
monitor.c | 5 -----
4 files changed, 21 insertions(+), 25 deletions(-)
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 1088ab0c78..c20d39049b 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -2514,7 +2514,9 @@
'dmg', 'file', 'ftp', 'ftps', 'gluster', 'host_cdrom',
'host_device', 'http', 'https', 'iscsi', 'luks', 'nbd', 'nfs',
'null-aio', 'null-co', 'nvme', 'parallels', 'qcow', 'qcow2', 'qed',
- 'quorum', 'raw', 'rbd', 'replication', 'sheepdog', 'ssh',
+ 'quorum', 'raw', 'rbd',
+ { 'name': 'replication', 'if': 'defined(CONFIG_REPLICATION)' },
+ 'sheepdog', 'ssh',
'throttle', 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat', 'vxhs' ] }
##
@@ -3228,7 +3230,8 @@
#
# Since: 2.9
##
-{ 'enum' : 'ReplicationMode', 'data' : [ 'primary', 'secondary' ] }
+{ 'enum' : 'ReplicationMode', 'data' : [ 'primary', 'secondary' ],
+ 'if': 'defined(CONFIG_REPLICATION)' }
##
# @BlockdevOptionsReplication:
@@ -3246,7 +3249,8 @@
{ 'struct': 'BlockdevOptionsReplication',
'base': 'BlockdevOptionsGenericFormat',
'data': { 'mode': 'ReplicationMode',
- '*top-id': 'str' } }
+ '*top-id': 'str' },
+ 'if': 'defined(CONFIG_REPLICATION)' }
##
# @NFSTransport:
@@ -3545,7 +3549,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 9d0bf82cf4..d2c6e4d646 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -1121,7 +1121,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:
@@ -1136,7 +1137,8 @@
# Since: 2.9
##
{ 'struct': 'ReplicationStatus',
- 'data': { 'error': 'bool', '*desc': 'str' } }
+ 'data': { 'error': 'bool', '*desc': 'str' },
+ 'if': 'defined(CONFIG_REPLICATION)' }
##
# @query-xen-replication-status:
@@ -1153,7 +1155,8 @@
# Since: 2.9
##
{ 'command': 'query-xen-replication-status',
- 'returns': 'ReplicationStatus' }
+ 'returns': 'ReplicationStatus',
+ 'if': 'defined(CONFIG_REPLICATION)' }
##
# @xen-colo-do-checkpoint:
@@ -1169,4 +1172,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 4381067ed4..2329e78e7f 100644
--- a/migration/colo.c
+++ b/migration/colo.c
@@ -24,7 +24,9 @@
#include "trace.h"
#include "qemu/error-report.h"
#include "migration/failover.h"
+#ifdef CONFIG_REPLICATION
#include "replication.h"
+#endif
static bool vmstate_loading;
@@ -148,11 +150,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;
@@ -171,14 +173,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);
@@ -193,19 +191,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 8a5539579b..88e6fd2e6f 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1087,11 +1087,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");
qmp_unregister_command(&qmp_commands, "query-sev");
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 38/49] build-sys: move qmp-introspect per target
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (36 preceding siblings ...)
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 37/49] qapi: add conditions to REPLICATION type/commands " Marc-André Lureau
@ 2018-03-21 11:52 ` Marc-André Lureau
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 39/49] qapi-commands: don't initialize command list in qmp_init_marshall() Marc-André Lureau
` (15 subsequent siblings)
53 siblings, 0 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:52 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
The following patches are going to introduce per-target #ifdef in the
schemas.
The introspection data is statically generated once, and must thus be
built per-target to reflect target-specific configuration.
Drop "do_test_visitor_in_qmp_introspect(&qmp_schema_qlit)" since the
schema is no longer in a common object. It is covered by the per-target
query-qmp-schema test instead.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
tests/test-qobject-input-visitor.c | 1 -
Makefile.objs | 2 --
Makefile.target | 2 ++
3 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/tests/test-qobject-input-visitor.c b/tests/test-qobject-input-visitor.c
index 6dc59c6211..e14544fc89 100644
--- a/tests/test-qobject-input-visitor.c
+++ b/tests/test-qobject-input-visitor.c
@@ -1270,7 +1270,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 c6c9b8fc21..f0b10dbf23 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -55,7 +55,6 @@ util-obj-y += qapi/qapi-events-tpm.o
util-obj-y += qapi/qapi-events-trace.o
util-obj-y += qapi/qapi-events-transaction.o
util-obj-y += qapi/qapi-events-ui.o
-util-obj-y += qapi/qapi-introspect.o
chardev-obj-y = chardev/
@@ -150,7 +149,6 @@ common-obj-y += qapi/qapi-commands-tpm.o
common-obj-y += qapi/qapi-commands-trace.o
common-obj-y += qapi/qapi-commands-transaction.o
common-obj-y += qapi/qapi-commands-ui.o
-common-obj-y += qapi/qapi-introspect.o
common-obj-y += qmp.o hmp.o
endif
diff --git a/Makefile.target b/Makefile.target
index 6549481096..0bb18dff9e 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -150,6 +150,8 @@ endif
GENERATED_FILES += hmp-commands.h hmp-commands-info.h
+obj-y += qapi/qapi-introspect.o
+
endif # CONFIG_SOFTMMU
# Workaround for http://gcc.gnu.org/PR55489, see configure.
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 39/49] qapi-commands: don't initialize command list in qmp_init_marshall()
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (37 preceding siblings ...)
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 38/49] build-sys: move qmp-introspect per target Marc-André Lureau
@ 2018-03-21 11:52 ` Marc-André Lureau
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 40/49] RFC: qapi: learn to split schema by 'top-unit' Marc-André Lureau
` (14 subsequent siblings)
53 siblings, 0 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:52 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
This will let the caller add several list of commands coming from
different schemas (the following patches split the schemas for common
and arch-specific parts).
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-cmds.c | 1 +
4 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/scripts/qapi/commands.py b/scripts/qapi/commands.py
index 40bb680b7c..3d3e97f737 100644
--- a/scripts/qapi/commands.py
+++ b/scripts/qapi/commands.py
@@ -220,8 +220,6 @@ def gen_registry(registry, prefix):
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 88e6fd2e6f..0d84c3edb4 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1121,6 +1121,7 @@ static 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 df1888edc1..6905c82b6c 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -1364,6 +1364,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-cmds.c b/tests/test-qmp-cmds.c
index e675722593..e723b440ca 100644
--- a/tests/test-qmp-cmds.c
+++ b/tests/test-qmp-cmds.c
@@ -285,6 +285,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.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 40/49] RFC: qapi: learn to split schema by 'top-unit'
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (38 preceding siblings ...)
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 39/49] qapi-commands: don't initialize command list in qmp_init_marshall() Marc-André Lureau
@ 2018-03-21 11:52 ` Marc-André Lureau
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 41/49] qapi: add a top-unit 'target' schema Marc-André Lureau
` (13 subsequent siblings)
53 siblings, 0 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:52 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
Another take at making the schema modular, this time by introducing
the concept of a 'top-unit'. With this approach, each module is part
of a top-unit, which is visited first before visiting the module
themselfs. The default 'top-unit' is None. Else, a module belong to a
'top-unit' whose name is given by the 'top-unit' pragma value.
This gives a chance to the generators to break generated output into
different files. The point of this excercice is to have modules that
can be compiled per qemu targets, instead of everything belonging to
the top schema without the right to use poisoin defines for
conditional compilation.
Generated types, visitors, events and commands are split by
'top-unit'.
The generated introspection and documentation remain monolithic.
TODO: if this approach is acceptable, write tests & doc.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi/commands.py | 22 +++++---
scripts/qapi/common.py | 105 +++++++++++++++++++++++++++++++--------
scripts/qapi/events.py | 33 ++++++++----
scripts/qapi/types.py | 8 +--
scripts/qapi/visit.py | 8 +--
5 files changed, 129 insertions(+), 47 deletions(-)
diff --git a/scripts/qapi/commands.py b/scripts/qapi/commands.py
index 3d3e97f737..3ca36fc33b 100644
--- a/scripts/qapi/commands.py
+++ b/scripts/qapi/commands.py
@@ -235,14 +235,20 @@ class QAPISchemaGenCommandVisitor(QAPISchemaModularCVisitor):
QAPISchemaModularCVisitor.__init__(
self, prefix, 'qapi-commands',
' * Schema-defined QAPI/QMP commands', __doc__)
+
+ def visit_unit_begin(self, unit):
+ super(self.__class__, self).visit_unit_begin(unit)
self._regy = QAPIGenCSnippet()
self._visited_ret_types = {}
- def _begin_module(self, name):
+ def _begin_module(self, name, main_module):
self._visited_ret_types[self._genc] = set()
- commands = self._module_basename('qapi-commands', name)
- types = self._module_basename('qapi-types', name)
- visit = self._module_basename('qapi-visit', name)
+ commands = self._module_basename('qapi-commands', name,
+ self._unit, main_module)
+ types = self._module_basename('qapi-types', name,
+ self._unit, main_module)
+ visit = self._module_basename('qapi-visit', name,
+ self._unit, main_module)
self._genc.add(mcgen('''
#include "qemu/osdep.h"
#include "qemu-common.h"
@@ -265,13 +271,13 @@ class QAPISchemaGenCommandVisitor(QAPISchemaModularCVisitor):
''',
types=types))
- def visit_end(self):
- (genc, genh) = self._module[self._main_module]
+ def visit_unit_end(self):
+ (genc, genh) = self.get_module_gen(self._main_module)
genh.add(mcgen('''
void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds);
''',
- c_prefix=c_name(self._prefix, protect=False)))
- genc.add(gen_registry(self._regy.get_content(), self._prefix))
+ c_prefix=c_name(self._prefix_unit(), protect=False)))
+ genc.add(gen_registry(self._regy.get_content(), self._prefix_unit()))
def visit_command(self, name, info, ifcond, arg_type, ret_type,
gen, success_response, boxed, allow_oob):
diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index 174b39ea50..bff8de05d1 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -271,11 +271,12 @@ class QAPISchemaParser(object):
self.exprs = []
self.docs = []
self.accept()
+ self._top_unit = None
cur_doc = None
while self.tok is not None:
info = {'file': self.fname, 'line': self.line,
- 'parent': self.incl_info}
+ 'parent': self.incl_info, 'top-unit': self._top_unit}
if self.tok == '#':
self.reject_expr_doc(cur_doc)
cur_doc = self.get_doc(info)
@@ -298,6 +299,9 @@ class QAPISchemaParser(object):
exprs_include = self._include(include, info, incl_fname,
previously_included)
if exprs_include:
+ incl_info = self.exprs[-1]['info']
+ if exprs_include._top_unit:
+ incl_info['has-pragma-top-unit'] = exprs_include._top_unit
self.exprs.extend(exprs_include.exprs)
self.docs.extend(exprs_include.docs)
elif "pragma" in expr:
@@ -356,6 +360,11 @@ class QAPISchemaParser(object):
raise QAPISemError(info,
"Pragma 'doc-required' must be boolean")
doc_required = value
+ elif name == 'top-unit':
+ if not isinstance(value, str):
+ raise QAPISemError(info,
+ "Pragma 'top-unit' must be a string")
+ self._top_unit = value
elif name == 'returns-whitelist':
if (not isinstance(value, list)
or any([not isinstance(elt, str) for elt in value])):
@@ -1098,6 +1107,11 @@ class QAPISchemaEntity(object):
def c_name(self):
return c_name(self.name)
+ def get_top_unit(self):
+ if self.info:
+ return self.info['top-unit']
+ return None
+
def check(self, schema):
if isinstance(self._ifcond, QAPISchemaType):
# inherit the condition from a type
@@ -1118,6 +1132,12 @@ class QAPISchemaVisitor(object):
def visit_begin(self, schema):
pass
+ def visit_unit_begin(self, unit):
+ pass
+
+ def visit_unit_end(self):
+ pass
+
def visit_end(self):
pass
@@ -1613,7 +1633,7 @@ class QAPISchema(object):
parser = QAPISchemaParser(open(fname, 'r'))
exprs = check_exprs(parser.exprs)
self.docs = parser.docs
- self._entity_list = []
+ self._entity_list = {} # dict of unit name -> list of entity
self._entity_dict = {}
self._predefining = True
self._def_predefineds()
@@ -1625,7 +1645,8 @@ class QAPISchema(object):
# Only the predefined types are allowed to not have info
assert ent.info or self._predefining
assert ent.name is None or ent.name not in self._entity_dict
- self._entity_list.append(ent)
+ entity_list = self._entity_list.setdefault(ent.get_top_unit(), [])
+ entity_list.append(ent)
if ent.name is not None:
self._entity_dict[ent.name] = ent
if ent.info:
@@ -1870,18 +1891,23 @@ class QAPISchema(object):
assert False
def check(self):
- for ent in self._entity_list:
- ent.check(self)
+ for unit in self._entity_list:
+ for ent in self._entity_list[unit]:
+ ent.check(self)
def visit(self, visitor):
visitor.visit_begin(self)
- module = None
- for entity in self._entity_list:
- if visitor.visit_needed(entity):
+ for unit in self._entity_list:
+ module = None
+ visitor.visit_unit_begin(unit)
+ for entity in self._entity_list[unit]:
+ if not visitor.visit_needed(entity):
+ continue
if entity.module != module:
module = entity.module
visitor.visit_module(module)
entity.visit(visitor)
+ visitor.visit_unit_end()
visitor.visit_end()
@@ -2301,6 +2327,19 @@ class QAPISchemaMonolithicCVisitor(QAPISchemaVisitor):
self._genh.write(output_dir, self._prefix + self._what + '.h')
+class QAPIGenCModule(object):
+
+ def __init__(self, blurb, pydoc, unit, main_module=False):
+ self.genc = QAPIGenC(blurb, pydoc)
+ self.genh = QAPIGenH(blurb, pydoc)
+ self.unit = unit
+ self.main_module = main_module
+
+ def write(self, output_dir, basename):
+ self.genc.write(output_dir, basename + '.c')
+ self.genh.write(output_dir, basename + '.h')
+
+
class QAPISchemaModularCVisitor(QAPISchemaVisitor):
def __init__(self, prefix, what, blurb, pydoc):
@@ -2309,48 +2348,70 @@ class QAPISchemaModularCVisitor(QAPISchemaVisitor):
self._blurb = blurb
self._pydoc = pydoc
self._module = {}
+ self._unit = None
self._main_module = None
- def _module_basename(self, what, name):
+ def _module_basename(self, what, name, unit=None, main_module=False):
if name is None:
return re.sub(r'-', '-builtin-', what)
basename = os.path.join(os.path.dirname(name),
self._prefix + what)
- if name == self._main_module:
+ if unit:
+ basename = unit + '-' + basename
+ if main_module:
return basename
return basename + '-' + os.path.splitext(os.path.basename(name))[0]
+ def _prefix_unit(self):
+ if self._unit:
+ return self._prefix + self._unit + '-'
+ return self._prefix
+
+ def visit_unit_begin(self, unit):
+ self._unit = unit
+ self._main_module = None
+
def _add_module(self, name, blurb):
- if self._main_module is None and name is not None:
+ main_module = False
+ if (name is not None and
+ ((self._unit is None and self._main_module is None) or
+ (self._unit == os.path.splitext(os.path.basename(name))[0]))):
self._main_module = name
- genc = QAPIGenC(blurb, self._pydoc)
- genh = QAPIGenH(blurb, self._pydoc)
- self._module[name] = (genc, genh)
+ main_module = True
+ self._module[name] = QAPIGenCModule(blurb, self._pydoc,
+ self._unit, main_module)
self._set_module(name)
+ return main_module
+
+ def get_module_gen(self, name):
+ mod = self._module[name]
+ return mod.genc, mod.genh
def _set_module(self, name):
- self._genc, self._genh = self._module[name]
+ self._genc, self._genh = self.get_module_gen(name)
def write(self, output_dir, opt_builtins=False):
for name in self._module:
if name is None and not opt_builtins:
continue
- basename = self._module_basename(self._what, name)
- (genc, genh) = self._module[name]
- genc.write(output_dir, basename + '.c')
- genh.write(output_dir, basename + '.h')
+ module = self._module[name]
+ basename = self._module_basename(self._what, name,
+ module.unit, module.main_module)
+ module.write(output_dir, basename)
- def _begin_module(self, name):
+ def _begin_module(self, name, main_module):
pass
def visit_module(self, name):
if name in self._module:
self._set_module(name)
return
- self._add_module(name, self._blurb)
- self._begin_module(name)
+ main_module = self._add_module(name, self._blurb)
+ self._begin_module(name, main_module)
def visit_include(self, name, info):
+ if 'has-pragma-top-unit' in info:
+ return
basename = self._module_basename(self._what, name)
self._genh.preamble_add(mcgen('''
#include "%(basename)s.h"
diff --git a/scripts/qapi/events.py b/scripts/qapi/events.py
index f02b65cf5a..88bfcfcf2a 100644
--- a/scripts/qapi/events.py
+++ b/scripts/qapi/events.py
@@ -58,7 +58,12 @@ def gen_param_var(typ):
return ret
-def gen_event_send(name, arg_type, boxed, event_enum_name):
+def gen_event_send(unit, name, arg_type, boxed, event_enum_name):
+ if not unit:
+ unit = ''
+ else:
+ unit += '_'
+
# FIXME: Our declaration of local variables (and of 'errp' in the
# parameter list) can collide with exploded members of the event's
# data type passed in as parameters. If this collision ever hits in
@@ -87,7 +92,7 @@ def gen_event_send(name, arg_type, boxed, event_enum_name):
ret += mcgen('''
- emit = qmp_event_get_func_emit();
+ emit = %(unit)sqmp_event_get_func_emit();
if (!emit) {
return;
}
@@ -95,7 +100,7 @@ def gen_event_send(name, arg_type, boxed, event_enum_name):
qmp = qmp_event_build_dict("%(name)s");
''',
- name=name)
+ name=name, unit=unit)
if arg_type and not arg_type.is_empty():
ret += mcgen('''
@@ -154,12 +159,17 @@ class QAPISchemaGenEventVisitor(QAPISchemaModularCVisitor):
QAPISchemaModularCVisitor.__init__(
self, prefix, 'qapi-events',
' * Schema-defined QAPI/QMP events', __doc__)
- self._enum_name = c_name(prefix + 'QAPIEvent', protect=False)
+
+ def visit_unit_begin(self, unit):
+ super(self.__class__, self).visit_unit_begin(unit)
+ self._enum_name = c_name(self._prefix_unit() + 'QAPIEvent', protect=False)
self._event_names = []
- def _begin_module(self, name):
- types = self._module_basename('qapi-types', name)
- visit = self._module_basename('qapi-visit', name)
+ def _begin_module(self, name, main_module):
+ types = self._module_basename('qapi-types', name,
+ self._unit, main_module)
+ visit = self._module_basename('qapi-visit', name,
+ self._unit, main_module)
self._genc.add(mcgen('''
#include "qemu/osdep.h"
#include "qemu-common.h"
@@ -171,7 +181,7 @@ class QAPISchemaGenEventVisitor(QAPISchemaModularCVisitor):
#include "qapi/qmp-event.h"
''',
- visit=visit, prefix=self._prefix))
+ visit=visit, prefix=self._prefix_unit()))
self._genh.add(mcgen('''
#include "qapi/util.h"
#include "%(types)s.h"
@@ -179,15 +189,16 @@ class QAPISchemaGenEventVisitor(QAPISchemaModularCVisitor):
''',
types=types))
- def visit_end(self):
- (genc, genh) = self._module[self._main_module]
+ def visit_unit_end(self):
+ (genc, genh) = self.get_module_gen(self._main_module)
genh.add(gen_enum(self._enum_name, self._event_names))
genc.add(gen_enum_lookup(self._enum_name, self._event_names))
def visit_event(self, name, info, ifcond, arg_type, boxed):
with ifcontext(ifcond, self._genh, self._genc):
self._genh.add(gen_event_send_decl(name, arg_type, boxed))
- self._genc.add(gen_event_send(name, arg_type, boxed, self._enum_name))
+ self._genc.add(gen_event_send(self._unit, name,
+ arg_type, boxed, self._enum_name))
self._event_names.append(QAPISchemaMember(name, ifcond))
diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py
index b0d3ddb596..ac0c4603d4 100644
--- a/scripts/qapi/types.py
+++ b/scripts/qapi/types.py
@@ -194,9 +194,11 @@ class QAPISchemaGenTypeVisitor(QAPISchemaModularCVisitor):
#include "qapi/util.h"
'''))
- def _begin_module(self, name):
- types = self._module_basename('qapi-types', name)
- visit = self._module_basename('qapi-visit', name)
+ def _begin_module(self, name, main_module):
+ types = self._module_basename('qapi-types', name,
+ self._unit, main_module)
+ visit = self._module_basename('qapi-visit', name,
+ self._unit, main_module)
self._genc.preamble_add(mcgen('''
#include "qemu/osdep.h"
#include "qapi/dealloc-visitor.h"
diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py
index dc5a3173fc..60625aae72 100644
--- a/scripts/qapi/visit.py
+++ b/scripts/qapi/visit.py
@@ -289,9 +289,11 @@ class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor):
''',
prefix=prefix))
- def _begin_module(self, name):
- types = self._module_basename('qapi-types', name)
- visit = self._module_basename('qapi-visit', name)
+ def _begin_module(self, name, main_module):
+ types = self._module_basename('qapi-types', name,
+ self._unit, main_module)
+ visit = self._module_basename('qapi-visit', name,
+ self._unit, main_module)
self._genc.preamble_add(mcgen('''
#include "qemu/osdep.h"
#include "qemu-common.h"
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 41/49] qapi: add a top-unit 'target' schema
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (39 preceding siblings ...)
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 40/49] RFC: qapi: learn to split schema by 'top-unit' Marc-André Lureau
@ 2018-03-21 11:52 ` Marc-André Lureau
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 42/49] qapi: make rtc-reset-reinjection and SEV depend on TARGET_I386 Marc-André Lureau
` (12 subsequent siblings)
53 siblings, 0 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:52 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
Add a 'target' top-unit to be compiled seperately from the common qapi
modules, in order to allow poisoined target #ifdef.
The generated commands must be registered seperately.
The events have a different enum, and must thus use a different
limiter/emitter.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qapi/qapi-schema.json | 1 +
qapi/target.json | 13 +++
include/qapi/qmp-event.h | 4 +
monitor.c | 205 ++++++++++++++++++++++++++-------------
qapi/qmp-event.c | 11 +++
Makefile | 1 +
Makefile.target | 2 +
7 files changed, 170 insertions(+), 67 deletions(-)
create mode 100644 qapi/target.json
diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json
index 25bce78352..6e7f85ae6d 100644
--- a/qapi/qapi-schema.json
+++ b/qapi/qapi-schema.json
@@ -93,3 +93,4 @@
{ 'include': 'trace.json' }
{ 'include': 'introspect.json' }
{ 'include': 'misc.json' }
+{ 'include': 'target.json' }
diff --git a/qapi/target.json b/qapi/target.json
new file mode 100644
index 0000000000..be2360ca34
--- /dev/null
+++ b/qapi/target.json
@@ -0,0 +1,13 @@
+# -*- Mode: Python -*-
+#
+
+##
+# = Target-specific commands & events
+##
+
+{ 'pragma': { 'top-unit': 'target' } }
+
+##
+# @DUMMY:
+##
+{ 'event': 'DUMMY' }
diff --git a/include/qapi/qmp-event.h b/include/qapi/qmp-event.h
index 0c87ad833e..cdf3b9b970 100644
--- a/include/qapi/qmp-event.h
+++ b/include/qapi/qmp-event.h
@@ -21,5 +21,9 @@ void qmp_event_set_func_emit(QMPEventFuncEmit emit);
QMPEventFuncEmit qmp_event_get_func_emit(void);
+void target_qmp_event_set_func_emit(QMPEventFuncEmit emit);
+
+QMPEventFuncEmit target_qmp_event_get_func_emit(void);
+
QDict *qmp_event_build_dict(const char *event_name);
#endif
diff --git a/monitor.c b/monitor.c
index 0d84c3edb4..0b96285e94 100644
--- a/monitor.c
+++ b/monitor.c
@@ -77,6 +77,8 @@
#include "block/qapi.h"
#include "qapi/qapi-commands.h"
#include "qapi/qapi-events.h"
+#include "qapi/target-qapi-commands.h"
+#include "qapi/target-qapi-events.h"
#include "qapi/error.h"
#include "qapi/qmp-event.h"
#include "qapi/qapi-introspect.h"
@@ -184,22 +186,25 @@ typedef struct {
GQueue *qmp_responses;
} MonitorQMP;
+typedef struct {
+ GHashTable *state;
+ const size_t size; /* size of array == number of events */
+ const int64_t rate[]; /* Minimum time (in ns) between two events */
+} MonitorQAPIEventRateLimit;
+
/*
* To prevent flooding clients, events can be throttled. The
* throttling is calculated globally, rather than per-Monitor
* instance.
*/
typedef struct MonitorQAPIEventState {
- QAPIEvent event; /* Throttling state for this event type and... */
+ const MonitorQAPIEventRateLimit *limiter;
+ unsigned event; /* Throttling state for this event type and... */
QDict *data; /* ... data, see qapi_event_throttle_equal() */
QEMUTimer *timer; /* Timer for handling delayed events */
QDict *qdict; /* Delayed event (if any) */
} MonitorQAPIEventState;
-typedef struct {
- int64_t rate; /* Minimum time (in ns) between two events */
-} MonitorQAPIEventConf;
-
struct Monitor {
CharBackend chr;
int reset_seen;
@@ -502,23 +507,11 @@ static void monitor_qmp_bh_responder(void *opaque)
}
}
-static MonitorQAPIEventConf monitor_qapi_event_conf[QAPI_EVENT__MAX] = {
- /* Limit guest-triggerable events to 1 per second */
- [QAPI_EVENT_RTC_CHANGE] = { 1000 * SCALE_MS },
- [QAPI_EVENT_WATCHDOG] = { 1000 * SCALE_MS },
- [QAPI_EVENT_BALLOON_CHANGE] = { 1000 * SCALE_MS },
- [QAPI_EVENT_QUORUM_REPORT_BAD] = { 1000 * SCALE_MS },
- [QAPI_EVENT_QUORUM_FAILURE] = { 1000 * SCALE_MS },
- [QAPI_EVENT_VSERPORT_CHANGE] = { 1000 * SCALE_MS },
-};
-
-GHashTable *monitor_qapi_event_state;
-
/*
* Emits the event to every monitor instance, @event is only used for trace
* Called with monitor_lock held.
*/
-static void monitor_qapi_event_emit(QAPIEvent event, QDict *qdict)
+static void monitor_qapi_event_emit(unsigned event, QDict *qdict)
{
Monitor *mon;
@@ -538,30 +531,31 @@ static void monitor_qapi_event_handler(void *opaque);
* applying any rate limiting if required.
*/
static void
-monitor_qapi_event_queue(QAPIEvent event, QDict *qdict, Error **errp)
+monitor_qapi_event_queue_limit(const MonitorQAPIEventRateLimit *limiter,
+ unsigned event, QDict *qdict, Error **errp)
{
- MonitorQAPIEventConf *evconf;
+ int64_t rate;
MonitorQAPIEventState *evstate;
- assert(event < QAPI_EVENT__MAX);
- evconf = &monitor_qapi_event_conf[event];
- trace_monitor_protocol_event_queue(event, qdict, evconf->rate);
+ assert(event < limiter->size);
+ rate = limiter->rate[event];
+ trace_monitor_protocol_event_queue(event, qdict, rate);
qemu_mutex_lock(&monitor_lock);
- if (!evconf->rate) {
+ if (!rate) {
/* Unthrottled event */
monitor_qapi_event_emit(event, qdict);
} else {
QDict *data = qobject_to(QDict, qdict_get(qdict, "data"));
MonitorQAPIEventState key = { .event = event, .data = data };
- evstate = g_hash_table_lookup(monitor_qapi_event_state, &key);
+ evstate = g_hash_table_lookup(limiter->state, &key);
assert(!evstate || timer_pending(evstate->timer));
if (evstate) {
/*
- * Timer is pending for (at least) evconf->rate ns after
+ * Timer is pending for (at least) rate ns after
* last send. Store event for sending when timer fires,
* replacing a prior stored event if any.
*/
@@ -570,9 +564,9 @@ monitor_qapi_event_queue(QAPIEvent event, QDict *qdict, Error **errp)
QINCREF(evstate->qdict);
} else {
/*
- * Last send was (at least) evconf->rate ns ago.
+ * Last send was (at least) rate ns ago.
* Send immediately, and arm the timer to call
- * monitor_qapi_event_handler() in evconf->rate ns. Any
+ * monitor_qapi_event_handler() in rate ns. Any
* events arriving before then will be delayed until then.
*/
int64_t now = qemu_clock_get_ns(event_clock_type);
@@ -580,6 +574,7 @@ monitor_qapi_event_queue(QAPIEvent event, QDict *qdict, Error **errp)
monitor_qapi_event_emit(event, qdict);
evstate = g_new(MonitorQAPIEventState, 1);
+ evstate->limiter = limiter;
evstate->event = event;
evstate->data = data;
QINCREF(evstate->data);
@@ -587,44 +582,14 @@ monitor_qapi_event_queue(QAPIEvent event, QDict *qdict, Error **errp)
evstate->timer = timer_new_ns(event_clock_type,
monitor_qapi_event_handler,
evstate);
- g_hash_table_add(monitor_qapi_event_state, evstate);
- timer_mod_ns(evstate->timer, now + evconf->rate);
+ g_hash_table_add(limiter->state, evstate);
+ timer_mod_ns(evstate->timer, now + rate);
}
}
qemu_mutex_unlock(&monitor_lock);
}
-/*
- * This function runs evconf->rate ns after sending a throttled
- * event.
- * If another event has since been stored, send it.
- */
-static void monitor_qapi_event_handler(void *opaque)
-{
- MonitorQAPIEventState *evstate = opaque;
- MonitorQAPIEventConf *evconf = &monitor_qapi_event_conf[evstate->event];
-
- trace_monitor_protocol_event_handler(evstate->event, evstate->qdict);
- qemu_mutex_lock(&monitor_lock);
-
- if (evstate->qdict) {
- int64_t now = qemu_clock_get_ns(event_clock_type);
-
- monitor_qapi_event_emit(evstate->event, evstate->qdict);
- QDECREF(evstate->qdict);
- evstate->qdict = NULL;
- timer_mod_ns(evstate->timer, now + evconf->rate);
- } else {
- g_hash_table_remove(monitor_qapi_event_state, evstate);
- QDECREF(evstate->data);
- timer_free(evstate->timer);
- g_free(evstate);
- }
-
- qemu_mutex_unlock(&monitor_lock);
-}
-
static unsigned int qapi_event_throttle_hash(const void *key)
{
const MonitorQAPIEventState *evstate = key;
@@ -663,15 +628,108 @@ static gboolean qapi_event_throttle_equal(const void *a, const void *b)
return TRUE;
}
+static void
+monitor_qapi_event_queue(unsigned event, QDict *qdict, Error **errp)
+{
+ static MonitorQAPIEventRateLimit limiter = {
+ .size = QAPI_EVENT__MAX,
+ .rate = {
+ /* Limit guest-triggerable events to 1 per second */
+ [QAPI_EVENT_RTC_CHANGE] = 1000 * SCALE_MS,
+ [QAPI_EVENT_WATCHDOG] = 1000 * SCALE_MS,
+ [QAPI_EVENT_BALLOON_CHANGE] = 1000 * SCALE_MS,
+ [QAPI_EVENT_QUORUM_REPORT_BAD] = 1000 * SCALE_MS,
+ [QAPI_EVENT_QUORUM_FAILURE] = 1000 * SCALE_MS,
+ [QAPI_EVENT_VSERPORT_CHANGE] = 1000 * SCALE_MS,
+ [QAPI_EVENT__MAX] = 0,
+ },
+ };
+
+ if (!limiter.state) {
+ limiter.state = g_hash_table_new(qapi_event_throttle_hash,
+ qapi_event_throttle_equal);
+ }
+
+ monitor_qapi_event_queue_limit(&limiter, event, qdict, errp);
+}
+
+static unsigned int target_qapi_event_throttle_hash(const void *key)
+{
+ const MonitorQAPIEventState *evstate = key;
+ unsigned int hash = evstate->event * 255;
+
+ return hash;
+}
+
+static gboolean target_qapi_event_throttle_equal(const void *a, const void *b)
+{
+ const MonitorQAPIEventState *eva = a;
+ const MonitorQAPIEventState *evb = b;
+
+ if (eva->event != evb->event) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+target_monitor_qapi_event_queue(unsigned event, QDict *qdict, Error **errp)
+{
+ static MonitorQAPIEventRateLimit limiter = {
+ .size = TARGET_QAPI_EVENT__MAX,
+ .rate = {
+ /* Limit guest-triggerable events to 1 per second */
+ [TARGET_QAPI_EVENT__MAX] = 0,
+ },
+ };
+
+ if (!limiter.state) {
+ limiter.state = g_hash_table_new(target_qapi_event_throttle_hash,
+ target_qapi_event_throttle_equal);
+ }
+ monitor_qapi_event_queue_limit(&limiter, event, qdict, errp);
+}
+
+/*
+ * This function runs evconf->rate ns after sending a throttled
+ * event.
+ * If another event has since been stored, send it.
+ */
+static void monitor_qapi_event_handler(void *opaque)
+{
+ MonitorQAPIEventState *evstate = opaque;
+ const MonitorQAPIEventRateLimit *limiter = evstate->limiter;
+ int64_t rate = limiter->rate[evstate->event];
+
+ trace_monitor_protocol_event_handler(evstate->event, evstate->qdict);
+ qemu_mutex_lock(&monitor_lock);
+
+ if (evstate->qdict) {
+ int64_t now = qemu_clock_get_ns(event_clock_type);
+
+ monitor_qapi_event_emit(evstate->event, evstate->qdict);
+ QDECREF(evstate->qdict);
+ evstate->qdict = NULL;
+ timer_mod_ns(evstate->timer, now + rate);
+ } else {
+ g_hash_table_remove(limiter->state, evstate);
+ QDECREF(evstate->data);
+ timer_free(evstate->timer);
+ g_free(evstate);
+ }
+
+ qemu_mutex_unlock(&monitor_lock);
+}
+
static void monitor_qapi_event_init(void)
{
if (qtest_enabled()) {
event_clock_type = QEMU_CLOCK_VIRTUAL;
}
- monitor_qapi_event_state = g_hash_table_new(qapi_event_throttle_hash,
- qapi_event_throttle_equal);
qmp_event_set_func_emit(monitor_qapi_event_queue);
+ target_qmp_event_set_func_emit(target_monitor_qapi_event_queue);
}
static void handle_hmp_command(Monitor *mon, const char *cmdline);
@@ -1039,9 +1097,10 @@ CommandInfoList *qmp_query_commands(Error **errp)
return list;
}
-EventInfoList *qmp_query_events(Error **errp)
+static void qmp_query_events_list(EventInfoList **list,
+ const QEnumLookup *qenum, int max)
{
- EventInfoList *info, *ev_list = NULL;
+ EventInfoList *info;
QAPIEvent e;
for (e = 0 ; e < QAPI_EVENT__MAX ; e++) {
@@ -1051,11 +1110,22 @@ EventInfoList *qmp_query_events(Error **errp)
info->value = g_malloc0(sizeof(*info->value));
info->value->name = g_strdup(event_name);
- info->next = ev_list;
- ev_list = info;
+ info->next = *list;
+ *list = info;
}
- return ev_list;
+}
+
+EventInfoList *qmp_query_events(Error **errp)
+{
+ EventInfoList *list = NULL;
+
+ qmp_query_events_list(&list, &QAPIEvent_lookup,
+ QAPI_EVENT__MAX);
+ qmp_query_events_list(&list, &target_QAPIEvent_lookup,
+ TARGET_QAPI_EVENT__MAX);
+
+ return list;
}
/*
@@ -1123,6 +1193,7 @@ static 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/qapi/qmp-event.c b/qapi/qmp-event.c
index 9d7e88e84a..72fd83841d 100644
--- a/qapi/qmp-event.c
+++ b/qapi/qmp-event.c
@@ -20,6 +20,7 @@
#include "qapi/qmp/qjson.h"
static QMPEventFuncEmit qmp_emit;
+static QMPEventFuncEmit target_qmp_emit;
void qmp_event_set_func_emit(QMPEventFuncEmit emit)
{
@@ -31,6 +32,16 @@ QMPEventFuncEmit qmp_event_get_func_emit(void)
return qmp_emit;
}
+void target_qmp_event_set_func_emit(QMPEventFuncEmit emit)
+{
+ target_qmp_emit = emit;
+}
+
+QMPEventFuncEmit target_qmp_event_get_func_emit(void)
+{
+ return target_qmp_emit;
+}
+
static void timestamp_put(QDict *qdict)
{
int err;
diff --git a/Makefile b/Makefile
index 727ef118f3..93a8ff5b78 100644
--- a/Makefile
+++ b/Makefile
@@ -588,6 +588,7 @@ qapi-modules = $(SRC_PATH)/qapi/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 \
diff --git a/Makefile.target b/Makefile.target
index 0bb18dff9e..9db617cda9 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -150,6 +150,8 @@ endif
GENERATED_FILES += hmp-commands.h hmp-commands-info.h
+obj-y += qapi/target-qapi-types.o qapi/target-qapi-visit.o
+obj-y += qapi/target-qapi-events.o qapi/target-qapi-commands.o
obj-y += qapi/qapi-introspect.o
endif # CONFIG_SOFTMMU
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 42/49] qapi: make rtc-reset-reinjection and SEV depend on TARGET_I386
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (40 preceding siblings ...)
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 41/49] qapi: add a top-unit 'target' schema Marc-André Lureau
@ 2018-03-21 11:52 ` Marc-André Lureau
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 43/49] qapi: make s390 commands depend on TARGET_S390X Marc-André Lureau
` (11 subsequent siblings)
53 siblings, 0 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:52 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
Move rtc-reset-reinjection and SEV in target.json and make them
conditional on TARGET_I386.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qapi/misc.json | 166 --------------------------------------
qapi/target.json | 175 ++++++++++++++++++++++++++++++++++++++++-
target/i386/sev_i386.h | 2 +-
hw/timer/mc146818rtc.c | 2 +-
monitor.c | 31 --------
5 files changed, 175 insertions(+), 201 deletions(-)
diff --git a/qapi/misc.json b/qapi/misc.json
index 5636f4a149..690eeda41f 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -3005,24 +3005,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:
#
@@ -3247,154 +3229,6 @@
##
{ 'command': 'query-vm-generation-id', 'returns': 'GuidInfo' }
-
-##
-# @SevState:
-#
-# An enumeration of SEV state information used during @query-sev.
-#
-# @uninit: The guest is uninitialized.
-#
-# @launch-update: The guest is currently being launched; plaintext data and
-# register state is being imported.
-#
-# @launch-secret: The guest is currently being launched; ciphertext data
-# is being imported.
-#
-# @running: The guest is fully launched or migrated in.
-#
-# @send-update: The guest is currently being migrated out to another machine.
-#
-# @receive-update: The guest is currently being migrated from another machine.
-#
-# Since: 2.12
-##
-{ 'enum': 'SevState',
- 'data': ['uninit', 'launch-update', 'launch-secret', 'running',
- 'send-update', 'receive-update' ] }
-
-##
-# @SevInfo:
-#
-# Information about Secure Encrypted Virtualization (SEV) support
-#
-# @enabled: true if SEV is active
-#
-# @api-major: SEV API major version
-#
-# @api-minor: SEV API minor version
-#
-# @build-id: SEV FW build id
-#
-# @policy: SEV policy value
-#
-# @state: SEV guest state
-#
-# @handle: SEV firmware handle
-#
-# Since: 2.12
-##
-{ 'struct': 'SevInfo',
- 'data': { 'enabled': 'bool',
- 'api-major': 'uint8',
- 'api-minor' : 'uint8',
- 'build-id' : 'uint8',
- 'policy' : 'uint32',
- 'state' : 'SevState',
- 'handle' : 'uint32'
- }
-}
-
-##
-# @query-sev:
-#
-# Returns information about SEV
-#
-# Returns: @SevInfo
-#
-# Since: 2.12
-#
-# Example:
-#
-# -> { "execute": "query-sev" }
-# <- { "return": { "enabled": true, "api-major" : 0, "api-minor" : 0,
-# "build-id" : 0, "policy" : 0, "state" : "running",
-# "handle" : 1 } }
-#
-##
-{ 'command': 'query-sev', 'returns': 'SevInfo' }
-
-##
-# @SevLaunchMeasureInfo:
-#
-# SEV Guest Launch measurement information
-#
-# @data: the measurement value encoded in base64
-#
-# Since: 2.12
-#
-##
-{ 'struct': 'SevLaunchMeasureInfo', 'data': {'data': 'str'} }
-
-##
-# @query-sev-launch-measure:
-#
-# Query the SEV guest launch information.
-#
-# Returns: The @SevLaunchMeasureInfo for the guest
-#
-# Since: 2.12
-#
-# Example:
-#
-# -> { "execute": "query-sev-launch-measure" }
-# <- { "return": { "data": "4l8LXeNlSPUDlXPJG5966/8%YZ" } }
-#
-##
-{ 'command': 'query-sev-launch-measure', 'returns': 'SevLaunchMeasureInfo' }
-
-##
-# @SevCapability:
-#
-# The struct describes capability for a Secure Encrypted Virtualization
-# feature.
-#
-# @pdh: Platform Diffie-Hellman key (base64 encoded)
-#
-# @cert-chain: PDH certificate chain (base64 encoded)
-#
-# @cbitpos: C-bit location in page table entry
-#
-# @reduced-phys-bits: Number of physical Address bit reduction when SEV is
-# enabled
-#
-# Since: 2.12
-##
-{ 'struct': 'SevCapability',
- 'data': { 'pdh': 'str',
- 'cert-chain': 'str',
- 'cbitpos': 'int',
- 'reduced-phys-bits': 'int'} }
-
-##
-# @query-sev-capabilities:
-#
-# This command is used to get the SEV capabilities, and is supported on AMD
-# X86 platforms only.
-#
-# Returns: SevCapability objects.
-#
-# Since: 2.12
-#
-# Example:
-#
-# -> { "execute": "query-sev-capabilities" }
-# <- { "return": { "pdh": "8CCDD8DDD", "cert-chain": "888CCCDDDEE",
-# "cbitpos": 47, "reduced-phys-bits": 5}}
-#
-##
-{ 'command': 'query-sev-capabilities', 'returns': 'SevCapability' }
-
##
# @CommandDropReason:
#
diff --git a/qapi/target.json b/qapi/target.json
index be2360ca34..f277b69a2a 100644
--- a/qapi/target.json
+++ b/qapi/target.json
@@ -8,6 +8,177 @@
{ 'pragma': { 'top-unit': 'target' } }
##
-# @DUMMY:
+# @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)' }
+
+
+##
+# @SevState:
+#
+# An enumeration of SEV state information used during @query-sev.
+#
+# @uninit: The guest is uninitialized.
+#
+# @launch-update: The guest is currently being launched; plaintext data and
+# register state is being imported.
+#
+# @launch-secret: The guest is currently being launched; ciphertext data
+# is being imported.
+#
+# @running: The guest is fully launched or migrated in.
+#
+# @send-update: The guest is currently being migrated out to another machine.
+#
+# @receive-update: The guest is currently being migrated from another machine.
+#
+# Since: 2.12
+##
+{ 'enum': 'SevState',
+ 'data': ['uninit', 'launch-update', 'launch-secret', 'running',
+ 'send-update', 'receive-update' ],
+ 'if': 'defined(TARGET_I386)' }
+
+##
+# @SevInfo:
+#
+# Information about Secure Encrypted Virtualization (SEV) support
+#
+# @enabled: true if SEV is active
+#
+# @api-major: SEV API major version
+#
+# @api-minor: SEV API minor version
+#
+# @build-id: SEV FW build id
+#
+# @policy: SEV policy value
+#
+# @state: SEV guest state
+#
+# @handle: SEV firmware handle
+#
+# Since: 2.12
+##
+{ 'struct': 'SevInfo',
+ 'data': { 'enabled': 'bool',
+ 'api-major': 'uint8',
+ 'api-minor' : 'uint8',
+ 'build-id' : 'uint8',
+ 'policy' : 'uint32',
+ 'state' : 'SevState',
+ 'handle' : 'uint32'
+ },
+ 'if': 'defined(TARGET_I386)'
+}
+
+##
+# @query-sev:
+#
+# Returns information about SEV
+#
+# Returns: @SevInfo
+#
+# Since: 2.12
+#
+# Example:
+#
+# -> { "execute": "query-sev" }
+# <- { "return": { "enabled": true, "api-major" : 0, "api-minor" : 0,
+# "build-id" : 0, "policy" : 0, "state" : "running",
+# "handle" : 1 } }
+#
+##
+{ 'command': 'query-sev', 'returns': 'SevInfo',
+ 'if': 'defined(TARGET_I386)' }
+
+
+##
+# @SevLaunchMeasureInfo:
+#
+# SEV Guest Launch measurement information
+#
+# @data: the measurement value encoded in base64
+#
+# Since: 2.12
+#
+##
+{ 'struct': 'SevLaunchMeasureInfo', 'data': {'data': 'str'},
+ 'if': 'defined(TARGET_I386)' }
+
+##
+# @query-sev-launch-measure:
+#
+# Query the SEV guest launch information.
+#
+# Returns: The @SevLaunchMeasureInfo for the guest
+#
+# Since: 2.12
+#
+# Example:
+#
+# -> { "execute": "query-sev-launch-measure" }
+# <- { "return": { "data": "4l8LXeNlSPUDlXPJG5966/8%YZ" } }
+#
+##
+{ 'command': 'query-sev-launch-measure', 'returns': 'SevLaunchMeasureInfo',
+ 'if': 'defined(TARGET_I386)' }
+
+
+##
+# @SevCapability:
+#
+# The struct describes capability for a Secure Encrypted Virtualization
+# feature.
+#
+# @pdh: Platform Diffie-Hellman key (base64 encoded)
+#
+# @cert-chain: PDH certificate chain (base64 encoded)
+#
+# @cbitpos: C-bit location in page table entry
+#
+# @reduced-phys-bits: Number of physical Address bit reduction when SEV is
+# enabled
+#
+# Since: 2.12
+##
+{ 'struct': 'SevCapability',
+ 'data': { 'pdh': 'str',
+ 'cert-chain': 'str',
+ 'cbitpos': 'int',
+ 'reduced-phys-bits': 'int'},
+ 'if': 'defined(TARGET_I386)' }
+
+##
+# @query-sev-capabilities:
+#
+# This command is used to get the SEV capabilities, and is supported on AMD
+# X86 platforms only.
+#
+# Returns: SevCapability objects.
+#
+# Since: 2.12
+#
+# Example:
+#
+# -> { "execute": "query-sev-capabilities" }
+# <- { "return": { "pdh": "8CCDD8DDD", "cert-chain": "888CCCDDDEE",
+# "cbitpos": 47, "reduced-phys-bits": 5}}
+#
##
-{ 'event': 'DUMMY' }
+{ 'command': 'query-sev-capabilities', 'returns': 'SevCapability',
+ 'if': 'defined(TARGET_I386)' }
diff --git a/target/i386/sev_i386.h b/target/i386/sev_i386.h
index b8622dfb1e..8f88f86952 100644
--- a/target/i386/sev_i386.h
+++ b/target/i386/sev_i386.h
@@ -19,7 +19,7 @@
#include "sysemu/kvm.h"
#include "sysemu/sev.h"
#include "qemu/error-report.h"
-#include "qapi/qapi-commands-misc.h"
+#include "qapi/target-qapi-commands.h"
#define SEV_POLICY_NODBG 0x1
#define SEV_POLICY_NOKS 0x2
diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c
index 6f1f723b1f..dd575ffbdf 100644
--- a/hw/timer/mc146818rtc.c
+++ b/hw/timer/mc146818rtc.c
@@ -31,7 +31,7 @@
#include "sysemu/replay.h"
#include "hw/timer/mc146818rtc.h"
#include "qapi/error.h"
-#include "qapi/qapi-commands-misc.h"
+#include "qapi/target-qapi-commands.h"
#include "qapi/qapi-events-misc.h"
#include "qapi/visitor.h"
diff --git a/monitor.c b/monitor.c
index 0b96285e94..4ad9225425 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1157,12 +1157,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");
- qmp_unregister_command(&qmp_commands, "query-sev");
- qmp_unregister_command(&qmp_commands, "query-sev-launch-measure");
- qmp_unregister_command(&qmp_commands, "query-sev-capabilities");
-#endif
#ifndef TARGET_S390X
qmp_unregister_command(&qmp_commands, "dump-skeys");
#endif
@@ -4709,31 +4703,6 @@ QemuOptsList qemu_mon_opts = {
},
};
-#ifndef TARGET_I386
-void qmp_rtc_reset_reinjection(Error **errp)
-{
- error_setg(errp, QERR_FEATURE_DISABLED, "rtc-reset-reinjection");
-}
-
-SevInfo *qmp_query_sev(Error **errp)
-{
- error_setg(errp, QERR_FEATURE_DISABLED, "query-sev");
- return NULL;
-}
-
-SevLaunchMeasureInfo *qmp_query_sev_launch_measure(Error **errp)
-{
- error_setg(errp, QERR_FEATURE_DISABLED, "query-sev-launch-measure");
- return NULL;
-}
-
-SevCapability *qmp_query_sev_capabilities(Error **errp)
-{
- error_setg(errp, QERR_FEATURE_DISABLED, "query-sev-capabilities");
- return NULL;
-}
-#endif
-
#ifndef TARGET_S390X
void qmp_dump_skeys(const char *filename, Error **errp)
{
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 43/49] qapi: make s390 commands depend on TARGET_S390X
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (41 preceding siblings ...)
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 42/49] qapi: make rtc-reset-reinjection and SEV depend on TARGET_I386 Marc-André Lureau
@ 2018-03-21 11:52 ` Marc-André Lureau
2018-03-22 5:42 ` Thomas Huth
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 44/49] target.json: add a note about query-cpu* not being s390x-specific Marc-André Lureau
` (10 subsequent siblings)
53 siblings, 1 reply; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:52 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Acked-by: Cornelia Huck <cohuck@redhat.com>
---
qapi/misc.json | 101 ----------------------
qapi/target.json | 106 ++++++++++++++++++++++++
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 | 13 ---
stubs/arch-query-cpu-model-comparison.c | 13 ---
target/s390x/cpu_models.c | 5 +-
stubs/Makefile.objs | 2 -
10 files changed, 110 insertions(+), 167 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/misc.json b/qapi/misc.json
index 690eeda41f..1753a81b1e 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -1821,27 +1821,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:
#
@@ -2208,46 +2187,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:
#
@@ -2260,46 +2199,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 f277b69a2a..b07a8926d8 100644
--- a/qapi/target.json
+++ b/qapi/target.json
@@ -7,6 +7,8 @@
{ 'pragma': { 'top-unit': 'target' } }
+{ 'include': 'misc.json' }
+
##
# @rtc-reset-reinjection:
#
@@ -182,3 +184,107 @@
##
{ 'command': 'query-sev-capabilities', 'returns': 'SevCapability',
'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 32abdfe6a1..f0ef652b2a 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -36,11 +36,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 76241c240e..59d28c2358 100644
--- a/hw/s390x/s390-skeys.c
+++ b/hw/s390x/s390-skeys.c
@@ -13,7 +13,7 @@
#include "hw/boards.h"
#include "hw/s390x/storage-keys.h"
#include "qapi/error.h"
-#include "qapi/qapi-commands-misc.h"
+#include "qapi/target-qapi-commands.h"
#include "qapi/qmp/qdict.h"
#include "qemu/error-report.h"
#include "sysemu/kvm.h"
diff --git a/monitor.c b/monitor.c
index 4ad9225425..bd9a6950cf 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1157,19 +1157,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");
@@ -4703,13 +4696,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 d8f80cb04e..14972b78df 100644
--- a/qmp.c
+++ b/qmp.c
@@ -601,20 +601,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 0d066da328..0000000000
--- a/stubs/arch-query-cpu-model-baseline.c
+++ /dev/null
@@ -1,13 +0,0 @@
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "sysemu/arch_init.h"
-#include "qapi/error.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 8eb311a26c..0000000000
--- a/stubs/arch-query-cpu-model-comparison.c
+++ /dev/null
@@ -1,13 +0,0 @@
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "sysemu/arch_init.h"
-#include "qapi/error.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 2741b6803f..ffca1d9a2d 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -25,6 +25,7 @@
#include "sysemu/arch_init.h"
#include "hw/pci/pci.h"
#endif
+#include "qapi/target-qapi-commands.h"
#define CPUDEF_INIT(_type, _gen, _ec_ga, _mha_pow, _hmfai, _name, _desc) \
{ \
@@ -597,7 +598,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)
{
@@ -670,7 +671,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 2d59d84091..9a91e49578 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.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 44/49] target.json: add a note about query-cpu* not being s390x-specific
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (42 preceding siblings ...)
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 43/49] qapi: make s390 commands depend on TARGET_S390X Marc-André Lureau
@ 2018-03-21 11:52 ` Marc-André Lureau
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 45/49] qapi: make query-gic-capabilities depend on TARGET_ARM Marc-André Lureau
` (9 subsequent siblings)
53 siblings, 0 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:52 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Acked-by: Cornelia Huck <cohuck@redhat.com>
---
qapi/target.json | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/qapi/target.json b/qapi/target.json
index b07a8926d8..be0ff84a6e 100644
--- a/qapi/target.json
+++ b/qapi/target.json
@@ -241,6 +241,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',
@@ -281,6 +284,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.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 45/49] qapi: make query-gic-capabilities depend on TARGET_ARM
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (43 preceding siblings ...)
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 44/49] target.json: add a note about query-cpu* not being s390x-specific Marc-André Lureau
@ 2018-03-21 11:52 ` Marc-André Lureau
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 46/49] qapi: make query-cpu-model-expansion depend on s390 or x86 Marc-André Lureau
` (8 subsequent siblings)
53 siblings, 0 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:52 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qapi/misc.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/misc.json b/qapi/misc.json
index 1753a81b1e..a0032120da 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -2965,49 +2965,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 be0ff84a6e..2ab18b38a9 100644
--- a/qapi/target.json
+++ b/qapi/target.json
@@ -294,3 +294,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 bd9a6950cf..67b433f12d 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1157,9 +1157,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
@@ -4696,14 +4693,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 4cdd2676dd..250405bf4d 100644
--- a/target/arm/monitor.c
+++ b/target/arm/monitor.c
@@ -23,7 +23,7 @@
#include "qemu/osdep.h"
#include "hw/boards.h"
#include "kvm_arm.h"
-#include "qapi/qapi-commands-misc.h"
+#include "qapi/target-qapi-commands.h"
static GICCapability *gic_cap_new(int version)
{
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 46/49] qapi: make query-cpu-model-expansion depend on s390 or x86
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (44 preceding siblings ...)
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 45/49] qapi: make query-gic-capabilities depend on TARGET_ARM Marc-André Lureau
@ 2018-03-21 11:52 ` Marc-André Lureau
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 47/49] qapi: make query-cpu-definitions depend on specific targets Marc-André Lureau
` (7 subsequent siblings)
53 siblings, 0 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:52 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Acked-by: Cornelia Huck <cohuck@redhat.com>
---
qapi/misc.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 | 13 ---------
target/i386/cpu.c | 3 +-
target/s390x/cpu_models.c | 2 +-
stubs/Makefile.objs | 1 -
9 files changed, 42 insertions(+), 67 deletions(-)
delete mode 100644 stubs/arch-query-cpu-model-expansion.c
diff --git a/qapi/misc.json b/qapi/misc.json
index a0032120da..602c99b174 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -2102,44 +2102,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 2ab18b38a9..323994a6ec 100644
--- a/qapi/target.json
+++ b/qapi/target.json
@@ -339,3 +339,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 f0ef652b2a..2497fd3351 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -33,7 +33,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 67b433f12d..63c51ee05d 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1157,9 +1157,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 14972b78df..9ded2f48c4 100644
--- a/qmp.c
+++ b/qmp.c
@@ -594,13 +594,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 26273a8b10..0000000000
--- a/stubs/arch-query-cpu-model-expansion.c
+++ /dev/null
@@ -1,13 +0,0 @@
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "sysemu/arch_init.h"
-#include "qapi/error.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 555ae79d29..563dad644c 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -39,6 +39,7 @@
#include "qapi/visitor.h"
#include "qom/qom-qobject.h"
#include "sysemu/arch_init.h"
+#include "qapi/target-qapi-commands.h"
#if defined(CONFIG_KVM)
#include <linux/kvm_para.h>
@@ -3125,7 +3126,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 ffca1d9a2d..e25034231d 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -559,7 +559,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 9a91e49578..1cd325841c 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.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 47/49] qapi: make query-cpu-definitions depend on specific targets
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (45 preceding siblings ...)
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 46/49] qapi: make query-cpu-model-expansion depend on s390 or x86 Marc-André Lureau
@ 2018-03-21 11:52 ` Marc-André Lureau
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 48/49] qapi: remove qmp_unregister_command() Marc-André Lureau
` (6 subsequent siblings)
53 siblings, 0 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:52 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
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>
Acked-by: Cornelia Huck <cohuck@redhat.com>
---
qapi/misc.json | 10 ----------
qapi/target.json | 12 ++++++++++++
include/sysemu/arch_init.h | 1 -
monitor.c | 22 ----------------------
qmp.c | 5 -----
stubs/arch-query-cpu-def.c | 11 -----------
target/arm/helper.c | 3 ++-
target/i386/cpu.c | 3 ++-
target/ppc/translate_init.c | 3 ++-
target/s390x/cpu_models.c | 2 +-
stubs/Makefile.objs | 1 -
11 files changed, 19 insertions(+), 54 deletions(-)
delete mode 100644 stubs/arch-query-cpu-def.c
diff --git a/qapi/misc.json b/qapi/misc.json
index 602c99b174..e9538ecae6 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -2027,16 +2027,6 @@
##
{ 'command': 'query-memory-size-summary', 'returns': 'MemoryInfo' }
-##
-# @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 323994a6ec..89ba4207b1 100644
--- a/qapi/target.json
+++ b/qapi/target.json
@@ -378,3 +378,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 2497fd3351..10cbafe970 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -32,5 +32,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 63c51ee05d..377ea3c98b 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1143,26 +1143,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
-}
-
static void monitor_init_qmp_commands(void)
{
/*
@@ -1184,8 +1164,6 @@ static 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 9ded2f48c4..cafda4417d 100644
--- a/qmp.c
+++ b/qmp.c
@@ -589,11 +589,6 @@ ObjectPropertyInfoList *qmp_qom_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 d436f95314..0000000000
--- a/stubs/arch-query-cpu-def.c
+++ /dev/null
@@ -1,11 +0,0 @@
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "sysemu/arch_init.h"
-#include "qapi/error.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 09893e3f72..ab8520f07d 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -17,6 +17,7 @@
#include "exec/semihost.h"
#include "sysemu/kvm.h"
#include "fpu/softfloat.h"
+#include "qapi/target-qapi-commands.h"
#define ARM_CPU_FREQ 1000000000 /* FIXME: 1 GHz, should be configurable */
@@ -5549,7 +5550,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 563dad644c..62c0c5b1eb 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -34,6 +34,7 @@
#include "qapi/error.h"
#include "qapi/qapi-visit-misc.h"
#include "qapi/qapi-visit-run-state.h"
+#include "qapi/target-qapi-commands.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qerror.h"
#include "qapi/visitor.h"
@@ -2865,7 +2866,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 391b94b97d..e679e8d301 100644
--- a/target/ppc/translate_init.c
+++ b/target/ppc/translate_init.c
@@ -39,6 +39,7 @@
#include "qemu/cutils.h"
#include "disas/capstone.h"
#include "fpu/softfloat.h"
+#include "qapi/target-qapi-commands.h"
//#define PPC_DUMP_CPU
//#define PPC_DEBUG_SPR
@@ -10298,7 +10299,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 e25034231d..c9b5216284 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -425,7 +425,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 1cd325841c..54f3e7e152 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.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 48/49] qapi: remove qmp_unregister_command()
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (46 preceding siblings ...)
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 47/49] qapi: make query-cpu-definitions depend on specific targets Marc-André Lureau
@ 2018-03-21 11:52 ` Marc-André Lureau
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 49/49] RFC: make RTC_CHANGE per-target Marc-André Lureau
` (5 subsequent siblings)
53 siblings, 0 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:52 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
This command is no longer needed after the schema is made conditional.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
include/qapi/qmp/dispatch.h | 1 -
qapi/qmp-registry.c | 8 --------
2 files changed, 9 deletions(-)
diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h
index ffb4652f71..dba9ee70b3 100644
--- a/include/qapi/qmp/dispatch.h
+++ b/include/qapi/qmp/dispatch.h
@@ -38,7 +38,6 @@ typedef QTAILQ_HEAD(QmpCommandList, QmpCommand) QmpCommandList;
void qmp_register_command(QmpCommandList *cmds, const char *name,
QmpCommandFunc *fn, QmpCommandOptions options);
-void qmp_unregister_command(QmpCommandList *cmds, const char *name);
QmpCommand *qmp_find_command(QmpCommandList *cmds, const char *name);
QObject *qmp_dispatch(QmpCommandList *cmds, QObject *request);
void qmp_disable_command(QmpCommandList *cmds, const char *name);
diff --git a/qapi/qmp-registry.c b/qapi/qmp-registry.c
index 5af484cd9a..ca00f74795 100644
--- a/qapi/qmp-registry.c
+++ b/qapi/qmp-registry.c
@@ -27,14 +27,6 @@ void qmp_register_command(QmpCommandList *cmds, const char *name,
QTAILQ_INSERT_TAIL(cmds, cmd, node);
}
-void qmp_unregister_command(QmpCommandList *cmds, const char *name)
-{
- QmpCommand *cmd = qmp_find_command(cmds, name);
-
- QTAILQ_REMOVE(cmds, cmd, node);
- g_free(cmd);
-}
-
QmpCommand *qmp_find_command(QmpCommandList *cmds, const char *name)
{
QmpCommand *cmd;
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* [Qemu-devel] [PATCH v3 49/49] RFC: make RTC_CHANGE per-target
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (47 preceding siblings ...)
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 48/49] qapi: remove qmp_unregister_command() Marc-André Lureau
@ 2018-03-21 11:52 ` Marc-André Lureau
2018-03-21 12:47 ` [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code no-reply
` (4 subsequent siblings)
53 siblings, 0 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-21 11:52 UTC (permalink / raw)
To: qemu-devel; +Cc: eblake, armbru, Marc-André Lureau
A few targets don't emit RTC_CHANGE, we could restrict the event to
the tagets that do emit it.
Note: There is a lot more of events & commands that we could restrict
to capable targets, with the cost of some additional complexity, but
the benefit of added correctness and better introspection.
Note2: The rate limite could perhaps be part of the schema, and the
common event emitter code, to simplify the need of custom and #ifdef
code in the monitor.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qapi/misc.json | 22 ----------------------
qapi/target.json | 23 +++++++++++++++++++++++
hw/ppc/spapr_rtc.c | 2 +-
hw/timer/mc146818rtc.c | 2 +-
monitor.c | 4 +++-
5 files changed, 28 insertions(+), 25 deletions(-)
diff --git a/qapi/misc.json b/qapi/misc.json
index e9538ecae6..6415bbb7fe 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -2856,28 +2856,6 @@
{ 'event': 'ACPI_DEVICE_OST',
'data': { 'info': 'ACPIOSTInfo' } }
-##
-# @RTC_CHANGE:
-#
-# Emitted when the guest changes the RTC time.
-#
-# @offset: offset between base RTC clock (as specified by -rtc base), and
-# new RTC clock value
-#
-# Note: This event is rate-limited.
-#
-# Since: 0.13.0
-#
-# Example:
-#
-# <- { "event": "RTC_CHANGE",
-# "data": { "offset": 78 },
-# "timestamp": { "seconds": 1267020223, "microseconds": 435656 } }
-#
-##
-{ 'event': 'RTC_CHANGE',
- 'data': { 'offset': 'int' } }
-
##
# @ReplayMode:
#
diff --git a/qapi/target.json b/qapi/target.json
index 89ba4207b1..b9f6741fbf 100644
--- a/qapi/target.json
+++ b/qapi/target.json
@@ -9,6 +9,29 @@
{ 'include': 'misc.json' }
+##
+# @RTC_CHANGE:
+#
+# Emitted when the guest changes the RTC time.
+#
+# @offset: offset between base RTC clock (as specified by -rtc base), and
+# new RTC clock value
+#
+# Note: This event is rate-limited.
+#
+# Since: 0.13.0
+#
+# Example:
+#
+# <- { "event": "RTC_CHANGE",
+# "data": { "offset": 78 },
+# "timestamp": { "seconds": 1267020223, "microseconds": 435656 } }
+#
+##
+{ 'event': 'RTC_CHANGE',
+ 'data': { 'offset': 'int' },
+ 'if': 'defined(TARGET_ALPHA) || defined(TARGET_ARM) || defined(TARGET_HPPA) || defined(TARGET_I386) || defined(TARGET_MIPS) || defined(TARGET_MIPS64) || defined(TARGET_MOXIE) || defined(TARGET_PPC) || defined(TARGET_PPC64) || defined(TARGET_S390X) || defined(TARGET_SH4) || defined(TARGET_SPARC)' }
+
##
# @rtc-reset-reinjection:
#
diff --git a/hw/ppc/spapr_rtc.c b/hw/ppc/spapr_rtc.c
index a37360537e..4cb73abf4a 100644
--- a/hw/ppc/spapr_rtc.c
+++ b/hw/ppc/spapr_rtc.c
@@ -31,7 +31,7 @@
#include "sysemu/sysemu.h"
#include "hw/ppc/spapr.h"
#include "qapi/error.h"
-#include "qapi/qapi-events-misc.h"
+#include "qapi/target-qapi-events.h"
#include "qemu/cutils.h"
void spapr_rtc_read(sPAPRRTCState *rtc, struct tm *tm, uint32_t *ns)
diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c
index dd575ffbdf..7de7562850 100644
--- a/hw/timer/mc146818rtc.c
+++ b/hw/timer/mc146818rtc.c
@@ -32,7 +32,7 @@
#include "hw/timer/mc146818rtc.h"
#include "qapi/error.h"
#include "qapi/target-qapi-commands.h"
-#include "qapi/qapi-events-misc.h"
+#include "qapi/target-qapi-events.h"
#include "qapi/visitor.h"
#ifdef TARGET_I386
diff --git a/monitor.c b/monitor.c
index 377ea3c98b..3c972206d9 100644
--- a/monitor.c
+++ b/monitor.c
@@ -635,7 +635,6 @@ monitor_qapi_event_queue(unsigned event, QDict *qdict, Error **errp)
.size = QAPI_EVENT__MAX,
.rate = {
/* Limit guest-triggerable events to 1 per second */
- [QAPI_EVENT_RTC_CHANGE] = 1000 * SCALE_MS,
[QAPI_EVENT_WATCHDOG] = 1000 * SCALE_MS,
[QAPI_EVENT_BALLOON_CHANGE] = 1000 * SCALE_MS,
[QAPI_EVENT_QUORUM_REPORT_BAD] = 1000 * SCALE_MS,
@@ -680,6 +679,9 @@ target_monitor_qapi_event_queue(unsigned event, QDict *qdict, Error **errp)
.size = TARGET_QAPI_EVENT__MAX,
.rate = {
/* Limit guest-triggerable events to 1 per second */
+#if defined(TARGET_ALPHA) || defined(TARGET_ARM) || defined(TARGET_HPPA) || defined(TARGET_I386) || defined(TARGET_MIPS) | defined(TARGET_MIPS64) || defined(TARGET_MOXIE) || defined(TARGET_PPC) || defined(TARGET_PPC64) || defined(TARGET_S390X) || defined(TARGET_SH4) || defined(TARGET_SPARC)
+ [TARGET_QAPI_EVENT_RTC_CHANGE] = 1000 * SCALE_MS,
+#endif
[TARGET_QAPI_EVENT__MAX] = 0,
},
};
--
2.16.2.521.g9aa15f885a
^ permalink raw reply related [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (48 preceding siblings ...)
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 49/49] RFC: make RTC_CHANGE per-target Marc-André Lureau
@ 2018-03-21 12:47 ` no-reply
2018-03-21 14:20 ` no-reply
` (3 subsequent siblings)
53 siblings, 0 replies; 95+ messages in thread
From: no-reply @ 2018-03-21 12:47 UTC (permalink / raw)
To: marcandre.lureau; +Cc: famz, qemu-devel, armbru
Hi,
This series failed build test on s390x host. Please find the details below.
Type: series
Message-id: 20180321115211.17937-1-marcandre.lureau@redhat.com
Subject: [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code
=== TEST SCRIPT BEGIN ===
#!/bin/bash
# Testing script will be invoked under the git checkout with
# HEAD pointing to a commit that has the patches applied on top of "base"
# branch
set -e
echo "=== ENV ==="
env
echo "=== PACKAGES ==="
rpm -qa
echo "=== TEST BEGIN ==="
CC=$HOME/bin/cc
INSTALL=$PWD/install
BUILD=$PWD/build
echo -n "Using CC: "
realpath $CC
mkdir -p $BUILD $INSTALL
SRC=$PWD
cd $BUILD
$SRC/configure --cc=$CC --prefix=$INSTALL
make -j4
# XXX: we need reliable clean up
# make check -j4 V=1
make install
=== TEST SCRIPT END ===
Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
* [new tag] patchew/1521634071-16519-1-git-send-email-stefanb@linux.vnet.ibm.com -> patchew/1521634071-16519-1-git-send-email-stefanb@linux.vnet.ibm.com
* [new tag] patchew/20180321115211.17937-1-marcandre.lureau@redhat.com -> patchew/20180321115211.17937-1-marcandre.lureau@redhat.com
* [new tag] patchew/20180321120853.14293-1-lvivier@redhat.com -> patchew/20180321120853.14293-1-lvivier@redhat.com
Switched to a new branch 'test'
ca50a2d8e3 RFC: make RTC_CHANGE per-target
032f3d2f59 qapi: remove qmp_unregister_command()
7a4b17cf54 qapi: make query-cpu-definitions depend on specific targets
557f536176 qapi: make query-cpu-model-expansion depend on s390 or x86
dc1b218319 qapi: make query-gic-capabilities depend on TARGET_ARM
af9625c6c3 target.json: add a note about query-cpu* not being s390x-specific
c9801977e9 qapi: make s390 commands depend on TARGET_S390X
6a49803445 qapi: make rtc-reset-reinjection and SEV depend on TARGET_I386
13b093aaae qapi: add a top-unit 'target' schema
8e42b4bfd8 RFC: qapi: learn to split schema by 'top-unit'
2984459cd6 qapi-commands: don't initialize command list in qmp_init_marshall()
7c39c807b5 build-sys: move qmp-introspect per target
af7d5d518d qapi: add conditions to REPLICATION type/commands on the schema
9e583d1a1d qapi: add conditions to SPICE type/commands/events on the schema
8bc16dec62 qapi: add conditions to VNC type/commands/events on the schema
72664dbe15 qapi2texi: add condition to variants
d7ff0ab4ef qapi2texi: add 'If:' condition to struct members
bde44a6b1d qapi2texi: add 'If:' condition to enum values
c87e1bc65f qapi2texi: add 'If:' section to generated documentation
3364d5099f docs: document schema configuration
77f7bafdc4 qapi: add #if conditions to generated code members
a95929de93 qapi: add 'if' to alternate members
b205d6198c qapi: add 'if' on union members
9613ba2cc2 qapi: add an error in case a discriminator is conditionnal
cd025039c0 qapi: add 'if' to implicit struct members
6799c824a8 qapi: add a dictionary form with 'type' key for members
c5b50ed9e3 qapi: rename allow_dict to allow_implicit
ba4011e602 qapi-event: add 'if' condition to implicit event enum
7d828e85b9 qapi: add 'if' to enum members
a20c2dc973 qapi: add a dictionnary form with 'name' key for enum members
061635eff1 qapi: factor out check_known_keys()
b0ad9a471a tests: modify visit_enum_type() in test-qapi to print members
86933fb39c qapi: change enum visitor to take QAPISchemaMember
cd6fb8e83f qapi: rename QAPISchemaEnumType.values to .members
31ea46dcec qapi: do not define enumeration value explicitely
55c7453f3c qapi-types: add #if conditions to types & visitors
4507e44d86 qapi-types: refactor variants handling
9c91a8fa1d qapi/events: add #if conditions to events
7ba12f474f qapi/commands: add #if conditions to commands
fcf4dfeb56 qapi-introspect: add preprocessor conditions to generated QLit
51163f6ba0 qapi-introspect: modify to_qlit() to append ', ' on level > 0
75baac460c qapi: add #if/#endif helpers
a001949a31 qapi: mcgen() shouldn't indent # lines
a2ef5afa63 qapi: add 'ifcond' to visitor methods
688755b5fd qapi: leave the ifcond attribute undefined until check()
0566f4cb49 qapi: pass 'if' condition into QAPISchemaEntity objects
7b98d1b34c qapi: add 'if' to top-level expressions
6c36d8fa28 qapi/events: generate event enum in main module
7ced623f53 qapi/visit: remove useless prefix argument
=== OUTPUT BEGIN ===
=== ENV ===
LANG=en_US.UTF-8
XDG_SESSION_ID=107260
USER=fam
PWD=/var/tmp/patchew-tester-tmp-1tgugnof/src
HOME=/home/fam
SHELL=/bin/sh
SHLVL=2
PATCHEW=/home/fam/patchew/patchew-cli -s http://patchew.org --nodebug
LOGNAME=fam
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1012/bus
XDG_RUNTIME_DIR=/run/user/1012
PATH=/usr/bin:/bin
_=/usr/bin/env
=== PACKAGES ===
gpg-pubkey-873529b8-54e386ff
glibc-debuginfo-common-2.24-10.fc25.s390x
fedora-release-26-1.noarch
dejavu-sans-mono-fonts-2.35-4.fc26.noarch
xemacs-filesystem-21.5.34-22.20170124hgf412e9f093d4.fc26.noarch
bash-4.4.12-7.fc26.s390x
freetype-2.7.1-9.fc26.s390x
libSM-1.2.2-5.fc26.s390x
libmpc-1.0.2-6.fc26.s390x
libaio-0.3.110-7.fc26.s390x
libverto-0.2.6-7.fc26.s390x
perl-Scalar-List-Utils-1.48-1.fc26.s390x
iptables-libs-1.6.1-2.fc26.s390x
p11-kit-trust-0.23.9-2.fc26.s390x
tcl-8.6.6-2.fc26.s390x
libxshmfence-1.2-4.fc26.s390x
expect-5.45-23.fc26.s390x
perl-Thread-Queue-3.12-1.fc26.noarch
perl-encoding-2.19-6.fc26.s390x
keyutils-1.5.10-1.fc26.s390x
gmp-devel-6.1.2-4.fc26.s390x
enchant-1.6.0-16.fc26.s390x
net-snmp-libs-5.7.3-17.fc26.s390x
python-gobject-base-3.24.1-1.fc26.s390x
python3-enchant-1.6.10-1.fc26.noarch
python-lockfile-0.11.0-6.fc26.noarch
python2-pyparsing-2.1.10-3.fc26.noarch
python2-lxml-4.1.1-1.fc26.s390x
librados2-10.2.7-2.fc26.s390x
trousers-lib-0.3.13-7.fc26.s390x
libpaper-1.1.24-14.fc26.s390x
libdatrie-0.2.9-4.fc26.s390x
libsoup-2.58.2-1.fc26.s390x
passwd-0.79-9.fc26.s390x
bind99-libs-9.9.10-3.P3.fc26.s390x
python3-rpm-4.13.0.2-1.fc26.s390x
systemd-233-7.fc26.s390x
virglrenderer-0.6.0-1.20170210git76b3da97b.fc26.s390x
s390utils-ziomon-1.36.1-3.fc26.s390x
s390utils-osasnmpd-1.36.1-3.fc26.s390x
libXrandr-1.5.1-2.fc26.s390x
libglvnd-glx-1.0.0-1.fc26.s390x
texlive-ifxetex-svn19685.0.5-33.fc26.2.noarch
texlive-psnfss-svn33946.9.2a-33.fc26.2.noarch
texlive-dvipdfmx-def-svn40328-33.fc26.2.noarch
texlive-natbib-svn20668.8.31b-33.fc26.2.noarch
texlive-xdvi-bin-svn40750-33.20160520.fc26.2.s390x
texlive-cm-svn32865.0-33.fc26.2.noarch
texlive-beton-svn15878.0-33.fc26.2.noarch
texlive-fpl-svn15878.1.002-33.fc26.2.noarch
texlive-mflogo-svn38628-33.fc26.2.noarch
texlive-texlive-docindex-svn41430-33.fc26.2.noarch
texlive-luaotfload-bin-svn34647.0-33.20160520.fc26.2.noarch
texlive-koma-script-svn41508-33.fc26.2.noarch
texlive-pst-tree-svn24142.1.12-33.fc26.2.noarch
texlive-breqn-svn38099.0.98d-33.fc26.2.noarch
texlive-xetex-svn41438-33.fc26.2.noarch
gstreamer1-plugins-bad-free-1.12.3-1.fc26.s390x
xorg-x11-font-utils-7.5-33.fc26.s390x
ghostscript-fonts-5.50-36.fc26.noarch
libXext-devel-1.3.3-5.fc26.s390x
libusbx-devel-1.0.21-2.fc26.s390x
libglvnd-devel-1.0.0-1.fc26.s390x
emacs-25.3-3.fc26.s390x
alsa-lib-devel-1.1.4.1-1.fc26.s390x
kbd-2.0.4-2.fc26.s390x
dconf-0.26.0-2.fc26.s390x
ccache-3.3.4-1.fc26.s390x
mc-4.8.19-5.fc26.s390x
doxygen-1.8.13-9.fc26.s390x
dpkg-1.18.24-1.fc26.s390x
libtdb-1.3.13-1.fc26.s390x
python2-pynacl-1.1.1-1.fc26.s390x
nss-sysinit-3.34.0-1.0.fc26.s390x
kernel-4.13.16-202.fc26.s390x
perl-Filter-1.58-1.fc26.s390x
python2-pip-9.0.1-11.fc26.noarch
dnf-2.7.5-2.fc26.noarch
sssd-common-1.16.0-4.fc26.s390x
python2-sssdconfig-1.16.0-4.fc26.noarch
bind-license-9.11.2-1.P1.fc26.noarch
libtasn1-4.13-1.fc26.s390x
glusterfs-fuse-3.10.10-1.fc26.s390x
cpp-7.3.1-2.fc26.s390x
pkgconf-1.3.12-2.fc26.s390x
python2-fedora-0.10.0-1.fc26.noarch
cmake-filesystem-3.10.1-11.fc26.s390x
selinux-policy-targeted-3.13.1-260.18.fc26.noarch
python3-requests-kerberos-0.12.0-1.fc26.noarch
libmicrohttpd-0.9.59-1.fc26.s390x
GeoIP-GeoLite-data-2018.01-1.fc26.noarch
glibc-debuginfo-2.24-10.fc25.s390x
dejavu-fonts-common-2.35-4.fc26.noarch
bind99-license-9.9.10-3.P3.fc26.noarch
ncurses-libs-6.0-8.20170212.fc26.s390x
libpng-1.6.28-2.fc26.s390x
libICE-1.0.9-9.fc26.s390x
perl-Text-ParseWords-3.30-366.fc26.noarch
libtool-ltdl-2.4.6-17.fc26.s390x
libselinux-utils-2.6-7.fc26.s390x
userspace-rcu-0.9.3-2.fc26.s390x
libXfont-1.5.2-5.fc26.s390x
perl-Class-Inspector-1.31-3.fc26.noarch
perl-open-1.10-395.fc26.noarch
keyutils-libs-devel-1.5.10-1.fc26.s390x
isl-0.16.1-1.fc26.s390x
libsecret-0.18.5-3.fc26.s390x
compat-openssl10-1.0.2m-1.fc26.s390x
python3-iniparse-0.4-24.fc26.noarch
python3-dateutil-2.6.0-3.fc26.noarch
python3-firewall-0.4.4.5-1.fc26.noarch
python-enum34-1.1.6-1.fc26.noarch
python2-pygments-2.2.0-7.fc26.noarch
python2-dockerfile-parse-0.0.7-1.fc26.noarch
perl-Net-SSLeay-1.81-1.fc26.s390x
hostname-3.18-2.fc26.s390x
libtirpc-1.0.2-0.fc26.s390x
rpm-build-libs-4.13.0.2-1.fc26.s390x
libutempter-1.1.6-9.fc26.s390x
systemd-pam-233-7.fc26.s390x
libXinerama-1.1.3-7.fc26.s390x
mesa-libGL-17.2.4-2.fc26.s390x
texlive-amsfonts-svn29208.3.04-33.fc26.2.noarch
texlive-caption-svn41409-33.fc26.2.noarch
texlive-enumitem-svn24146.3.5.2-33.fc26.2.noarch
texlive-pdftex-def-svn22653.0.06d-33.fc26.2.noarch
texlive-xdvi-svn40768-33.fc26.2.noarch
texlive-courier-svn35058.0-33.fc26.2.noarch
texlive-charter-svn15878.0-33.fc26.2.noarch
texlive-graphics-def-svn41879-33.fc26.2.noarch
texlive-mfnfss-svn19410.0-33.fc26.2.noarch
texlive-texlive-en-svn41185-33.fc26.2.noarch
texlive-ifplatform-svn21156.0.4-33.fc26.2.noarch
texlive-ms-svn29849.0-33.fc26.2.noarch
texlive-pst-tools-svn34067.0.05-33.fc26.2.noarch
texlive-powerdot-svn38984-33.fc26.2.noarch
texlive-xetexconfig-svn41133-33.fc26.2.noarch
libvdpau-1.1.1-4.fc26.s390x
zlib-devel-1.2.11-2.fc26.s390x
gdk-pixbuf2-devel-2.36.9-1.fc26.s390x
libX11-devel-1.6.5-2.fc26.s390x
libglvnd-core-devel-1.0.0-1.fc26.s390x
SDL2-devel-2.0.7-2.fc26.s390x
webkitgtk3-2.4.11-5.fc26.s390x
grubby-8.40-4.fc26.s390x
uboot-tools-2017.05-4.fc26.s390x
cracklib-dicts-2.9.6-5.fc26.s390x
texinfo-6.3-3.fc26.s390x
time-1.7-52.fc26.s390x
python2-deltarpm-3.6-19.fc26.s390x
nss-3.34.0-1.0.fc26.s390x
python2-setuptools-37.0.0-1.fc26.noarch
python2-dnf-2.7.5-2.fc26.noarch
groff-base-1.22.3-10.fc26.s390x
python2-devel-2.7.14-4.fc26.s390x
python2-GitPython-2.1.7-2.fc26.noarch
boost-iostreams-1.63.0-10.fc26.s390x
distribution-gpg-keys-1.18-1.fc26.noarch
glusterfs-client-xlators-3.10.10-1.fc26.s390x
cups-libs-2.2.2-8.fc26.s390x
bind-libs-lite-9.11.2-1.P1.fc26.s390x
libpkgconf-1.3.12-2.fc26.s390x
python2-rpkg-1.51-3.fc26.noarch
java-1.8.0-openjdk-headless-1.8.0.161-5.b14.fc26.s390x
fedpkg-1.31-5.fc26.noarch
python3-dnf-plugin-system-upgrade-2.0.5-1.fc26.noarch
dtc-1.4.6-1.fc26.s390x
fedora-repos-26-2.noarch
gpg-pubkey-efe550f5-5220ba41
gpg-pubkey-81b46521-55b3ca9a
filesystem-3.2-40.fc26.s390x
basesystem-11-3.fc26.noarch
js-jquery-3.2.1-1.fc26.noarch
elfutils-libelf-0.169-1.fc26.s390x
libidn-1.33-2.fc26.s390x
libogg-1.3.2-6.fc26.s390x
slang-2.3.1a-2.fc26.s390x
apr-1.6.3-1.fc26.s390x
libxkbcommon-0.7.1-3.fc26.s390x
perl-IO-1.36-395.fc26.s390x
libvorbis-1.3.5-2.fc26.s390x
less-487-3.fc26.s390x
lttng-ust-2.9.0-2.fc26.s390x
OpenEXR-libs-2.2.0-6.fc26.s390x
ipset-libs-6.29-3.fc26.s390x
perl-XML-XPath-1.42-1.fc26.noarch
lua-filesystem-1.6.3-3.fc24.s390x
sqlite-3.20.1-1.fc26.s390x
gstreamer1-1.12.3-1.fc26.s390x
libpwquality-1.3.0-8.fc26.s390x
gettext-libs-0.19.8.1-9.fc26.s390x
python3-chardet-2.3.0-3.fc26.noarch
python3-slip-dbus-0.6.4-6.fc26.noarch
python-chardet-2.3.0-3.fc26.noarch
python2-pyasn1-0.2.3-1.fc26.noarch
python-slip-dbus-0.6.4-6.fc26.noarch
libarchive-3.2.2-4.fc26.s390x
libbabeltrace-1.5.2-2.fc26.s390x
cdparanoia-libs-10.2-22.fc26.s390x
krb5-workstation-1.15.2-4.fc26.s390x
gpgme-1.8.0-12.fc26.s390x
python2-gpg-1.8.0-12.fc26.s390x
shadow-utils-4.3.1-3.fc26.s390x
cryptsetup-libs-1.7.5-1.fc26.s390x
kpartx-0.4.9-88.fc26.s390x
net-snmp-agent-libs-5.7.3-17.fc26.s390x
libXi-1.7.9-2.fc26.s390x
texlive-tetex-svn41059-33.fc26.2.noarch
texlive-tools-svn40934-33.fc26.2.noarch
texlive-bibtex-bin-svn40473-33.20160520.fc26.2.s390x
texlive-mfware-bin-svn40473-33.20160520.fc26.2.s390x
texlive-underscore-svn18261.0-33.fc26.2.noarch
texlive-avantgar-svn31835.0-33.fc26.2.noarch
texlive-anysize-svn15878.0-33.fc26.2.noarch
texlive-lineno-svn21442.4.41-33.fc26.2.noarch
texlive-mathpazo-svn15878.1.003-33.fc26.2.noarch
texlive-soul-svn15878.2.4-33.fc26.2.noarch
texlive-luatexbase-svn38550-33.fc26.2.noarch
texlive-listings-svn37534.1.6-33.fc26.2.noarch
texlive-pstricks-svn41321-33.fc26.2.noarch
texlive-metalogo-svn18611.0.12-33.fc26.2.noarch
texlive-dvipdfmx-svn41149-33.fc26.2.noarch
kbd-legacy-2.0.4-2.fc26.noarch
nspr-devel-4.17.0-1.fc26.s390x
ghostscript-x11-9.20-10.fc26.s390x
libXrender-devel-0.9.10-2.fc26.s390x
libxkbcommon-devel-0.7.1-3.fc26.s390x
mesa-libGL-devel-17.2.4-2.fc26.s390x
sqlite-devel-3.20.1-1.fc26.s390x
usbredir-devel-0.7.1-3.fc26.s390x
libcap-devel-2.25-5.fc26.s390x
brlapi-devel-0.6.6-5.fc26.s390x
python3-pygpgme-0.3-22.fc26.s390x
pinentry-0.9.7-3.fc26.s390x
perl-Test-Harness-3.39-1.fc26.noarch
qemu-sanity-check-nodeps-1.1.5-6.fc26.s390x
libldb-1.1.29-5.fc26.s390x
nss-util-devel-3.34.0-1.0.fc26.s390x
python2-2.7.14-4.fc26.s390x
libwayland-cursor-1.13.0-3.fc26.s390x
pulseaudio-libs-devel-11.1-7.fc26.s390x
json-c-0.12.1-5.fc26.s390x
kernel-headers-4.15.4-200.fc26.s390x
libgcrypt-1.8.2-1.fc26.s390x
libgo-devel-7.3.1-2.fc26.s390x
glusterfs-cli-3.10.10-1.fc26.s390x
glusterfs-server-3.10.10-1.fc26.s390x
redhat-rpm-config-64-1.fc26.noarch
ca-certificates-2018.2.22-1.0.fc26.noarch
python2-sphinx-1.5.6-1.fc26.noarch
libtevent-0.9.35-1.fc26.s390x
dnsmasq-2.76-6.fc26.s390x
perl-Module-CoreList-5.20180120-1.fc26.noarch
gpg-pubkey-34ec9cba-54e38751
gpg-pubkey-030d5aed-55b577f0
setup-2.10.5-2.fc26.noarch
lato-fonts-2.015-3.fc26.noarch
web-assets-filesystem-5-5.fc26.noarch
libsepol-2.6-2.fc26.s390x
libcap-2.25-5.fc26.s390x
tcp_wrappers-libs-7.6-85.fc26.s390x
libnl3-3.3.0-1.fc26.s390x
pixman-0.34.0-3.fc26.s390x
lzo-2.08-9.fc26.s390x
perl-5.24.3-395.fc26.s390x
libnl3-cli-3.3.0-1.fc26.s390x
gpm-libs-1.20.7-10.fc26.s390x
iso-codes-3.74-2.fc26.noarch
ipset-6.29-3.fc26.s390x
lua-term-0.07-1.fc25.s390x
libdb-utils-5.3.28-24.fc26.s390x
dbus-glib-0.108-2.fc26.s390x
pam-1.3.0-2.fc26.s390x
avahi-glib-0.6.32-7.fc26.s390x
python2-dateutil-2.6.0-3.fc26.noarch
python3-asn1crypto-0.23.0-1.fc26.noarch
python3-slip-0.6.4-6.fc26.noarch
python-backports-ssl_match_hostname-3.5.0.1-4.fc26.noarch
python2-pyOpenSSL-16.2.0-6.fc26.noarch
python-slip-0.6.4-6.fc26.noarch
nss-pem-1.0.3-3.fc26.s390x
fipscheck-1.5.0-1.fc26.s390x
elfutils-0.169-1.fc26.s390x
cyrus-sasl-lib-2.1.26-32.fc26.s390x
libkadm5-1.15.2-4.fc26.s390x
python3-kerberos-1.2.5-3.fc26.s390x
rpmconf-1.0.19-1.fc26.noarch
libsemanage-2.6-4.fc26.s390x
device-mapper-libs-1.02.137-6.fc26.s390x
yum-3.4.3-512.fc26.noarch
device-mapper-multipath-0.4.9-88.fc26.s390x
net-snmp-5.7.3-17.fc26.s390x
libXtst-1.2.3-2.fc26.s390x
libXxf86vm-1.1.4-4.fc26.s390x
texlive-amsmath-svn41561-33.fc26.2.noarch
texlive-xkeyval-svn35741.2.7a-33.fc26.2.noarch
texlive-bibtex-svn40768-33.fc26.2.noarch
texlive-mfware-svn40768-33.fc26.2.noarch
texlive-wasy-svn35831.0-33.fc26.2.noarch
texlive-bookman-svn31835.0-33.fc26.2.noarch
texlive-babel-english-svn30264.3.3p-33.fc26.2.noarch
texlive-fix2col-svn38770-33.fc26.2.noarch
texlive-mdwtools-svn15878.1.05.4-33.fc26.2.noarch
texlive-tex-gyre-math-svn41264-33.fc26.2.noarch
texlive-luaotfload-svn40902-33.fc26.2.noarch
texlive-showexpl-svn32737.v0.3l-33.fc26.2.noarch
texlive-pstricks-add-svn40744-33.fc26.2.noarch
texlive-l3experimental-svn41163-33.fc26.2.noarch
texlive-xetex-bin-svn41091-33.20160520.fc26.2.s390x
kbd-misc-2.0.4-2.fc26.noarch
libpng-devel-1.6.28-2.fc26.s390x
ghostscript-core-9.20-10.fc26.s390x
libXfixes-devel-5.0.3-2.fc26.s390x
libverto-devel-0.2.6-7.fc26.s390x
mesa-libEGL-devel-17.2.4-2.fc26.s390x
popt-devel-1.16-12.fc26.s390x
readline-devel-7.0-5.fc26.s390x
cyrus-sasl-devel-2.1.26-32.fc26.s390x
sendmail-8.15.2-19.fc26.s390x
systemd-bootchart-231-3.fc26.s390x
perl-IO-Socket-SSL-2.049-1.fc26.noarch
python2-enchant-1.6.10-1.fc26.noarch
perl-generators-1.10-2.fc26.noarch
createrepo-0.10.3-11.fc26.noarch
nss-tools-3.34.0-1.0.fc26.s390x
pulseaudio-libs-glib2-11.1-7.fc26.s390x
dhcp-libs-4.3.5-10.fc26.s390x
libtiff-4.0.9-1.fc26.s390x
python-srpm-macros-3-21.fc26.noarch
libcurl-7.53.1-14.fc26.s390x
gnupg2-2.2.4-1.fc26.s390x
libtalloc-2.1.11-1.fc26.s390x
nfs-utils-2.2.1-4.rc2.fc26.s390x
qt5-srpm-macros-5.9.4-2.fc26.noarch
python2-dnf-plugins-core-2.1.5-4.fc26.noarch
mariadb-libs-10.1.30-2.fc26.s390x
bind-libs-9.11.2-1.P1.fc26.s390x
acpica-tools-20180105-1.fc26.s390x
perl-podlators-4.09-3.fc26.noarch
fontpackages-filesystem-1.44-18.fc26.noarch
vte-profile-0.48.4-1.fc26.s390x
texlive-kpathsea-doc-svn41139-33.fc26.2.noarch
zlib-1.2.11-2.fc26.s390x
readline-7.0-5.fc26.s390x
libattr-2.4.47-18.fc26.s390x
libglvnd-1.0.0-1.fc26.s390x
lz4-libs-1.8.0-1.fc26.s390x
jansson-2.10-2.fc26.s390x
perl-File-Path-2.12-367.fc26.noarch
perl-Unicode-EastAsianWidth-1.33-9.fc26.noarch
hunspell-1.5.4-2.fc26.s390x
libasyncns-0.8-11.fc26.s390x
libnetfilter_conntrack-1.0.6-2.fc26.s390x
perl-Storable-2.56-368.fc26.s390x
autoconf-2.69-24.fc26.noarch
device-mapper-persistent-data-0.6.3-5.fc26.s390x
quota-4.03-9.fc26.s390x
crypto-policies-20170606-1.git7c32281.fc26.noarch
glib2-2.52.3-2.fc26.s390x
python2-idna-2.5-1.fc26.noarch
python2-libcomps-0.1.8-3.fc26.s390x
gsettings-desktop-schemas-3.24.1-1.fc26.s390x
javapackages-tools-4.7.0-17.fc26.noarch
libselinux-python3-2.6-7.fc26.s390x
python-backports-1.0-9.fc26.s390x
python2-cryptography-2.0.2-2.fc26.s390x
libselinux-python-2.6-7.fc26.s390x
Lmod-7.5.3-1.fc26.s390x
fipscheck-lib-1.5.0-1.fc26.s390x
elfutils-libs-0.169-1.fc26.s390x
krb5-libs-1.15.2-4.fc26.s390x
libuser-0.62-6.fc26.s390x
npth-1.5-1.fc26.s390x
packagedb-cli-2.14.1-2.fc26.noarch
ustr-1.0.4-22.fc26.s390x
device-mapper-1.02.137-6.fc26.s390x
polkit-pkla-compat-0.1-8.fc26.s390x
fakeroot-1.22-1.fc26.s390x
libXmu-1.1.2-5.fc26.s390x
cairo-gobject-1.14.10-1.fc26.s390x
texlive-booktabs-svn40846-33.fc26.2.noarch
texlive-dvips-bin-svn40987-33.20160520.fc26.2.s390x
texlive-float-svn15878.1.3d-33.fc26.2.noarch
texlive-tex-svn40793-33.fc26.2.noarch
texlive-fancyref-svn15878.0.9c-33.fc26.2.noarch
texlive-manfnt-font-svn35799.0-33.fc26.2.noarch
texlive-cmap-svn41168-33.fc26.2.noarch
texlive-hyph-utf8-svn41189-33.fc26.2.noarch
texlive-paralist-svn39247-33.fc26.2.noarch
texlive-trimspaces-svn15878.1.1-33.fc26.2.noarch
texlive-tipa-svn29349.1.3-33.fc26.2.noarch
texlive-l3packages-svn41246-33.fc26.2.noarch
texlive-pst-pdf-svn31660.1.1v-33.fc26.2.noarch
texlive-tex-gyre-svn18651.2.004-33.fc26.2.noarch
texlive-beamer-svn36461.3.36-33.fc26.2.noarch
gd-2.2.5-1.fc26.s390x
elfutils-libelf-devel-0.169-1.fc26.s390x
gc-devel-7.6.0-2.fc26.s390x
libXft-devel-2.3.2-5.fc26.s390x
krb5-devel-1.15.2-4.fc26.s390x
rpm-devel-4.13.0.2-1.fc26.s390x
bluez-libs-devel-5.46-6.fc26.s390x
systemtap-3.2-2.fc26.s390x
trousers-0.3.13-7.fc26.s390x
iproute-tc-4.11.0-1.fc26.s390x
libgnome-keyring-3.12.0-8.fc26.s390x
perl-File-ShareDir-1.102-8.fc26.noarch
python2-paramiko-2.2.1-1.fc26.noarch
python2-openidc-client-0.4.0-1.20171113git54dee6e.fc26.noarch
openssh-server-7.5p1-4.fc26.s390x
pulseaudio-libs-11.1-7.fc26.s390x
python2-bodhi-2.12.2-3.fc26.noarch
lua-libs-5.3.4-7.fc26.s390x
dhcp-common-4.3.5-10.fc26.noarch
python3-pip-9.0.1-11.fc26.noarch
python3-sssdconfig-1.16.0-4.fc26.noarch
python2-py-1.4.34-1.fc26.noarch
glibc-common-2.25-13.fc26.s390x
webkitgtk4-jsc-2.18.6-1.fc26.s390x
python3-libs-3.6.4-2.fc26.s390x
glibc-devel-2.25-13.fc26.s390x
pcre2-10.23-13.fc26.s390x
linux-firmware-20171215-82.git2451bb22.fc26.noarch
glusterfs-api-devel-3.10.10-1.fc26.s390x
libfdt-devel-1.4.6-1.fc26.s390x
audit-2.8.2-1.fc26.s390x
perl-Socket-2.027-1.fc26.s390x
nosync-1.0-6.fc26.s390x
gpg-pubkey-95a43f54-5284415a
gpg-pubkey-fdb19c98-56fd6333
gpg-pubkey-64dab85d-57d33e22
firewalld-filesystem-0.4.4.5-1.fc26.noarch
xkeyboard-config-2.21-3.fc26.noarch
texlive-texlive-common-doc-svn40682-33.fc26.2.noarch
ncurses-base-6.0-8.20170212.fc26.noarch
libselinux-2.6-7.fc26.s390x
bzip2-libs-1.0.6-22.fc26.s390x
libdb-5.3.28-24.fc26.s390x
mpfr-3.1.5-3.fc26.s390x
file-libs-5.30-11.fc26.s390x
libunistring-0.9.7-1.fc26.s390x
libxslt-1.1.29-1.fc26.s390x
gdbm-1.13-1.fc26.s390x
libepoxy-1.4.3-1.fc26.s390x
libpsl-0.18.0-1.fc26.s390x
perl-Carp-1.40-366.fc26.noarch
e2fsprogs-libs-1.43.4-2.fc26.s390x
libmnl-1.0.4-2.fc26.s390x
openjpeg2-2.2.0-3.fc26.s390x
perl-PathTools-3.63-367.fc26.s390x
perl-File-Temp-0.230.400-2.fc26.noarch
perl-XML-Parser-2.44-6.fc26.s390x
libss-1.43.4-2.fc26.s390x
ilmbase-2.2.0-8.fc26.s390x
fuse-libs-2.9.7-2.fc26.s390x
libdaemon-0.14-11.fc26.s390x
libbasicobjects-0.1.1-34.fc26.s390x
iptables-1.6.1-2.fc26.s390x
perl-TermReadKey-2.37-2.fc26.s390x
perl-Term-ANSIColor-4.06-2.fc26.noarch
perl-libintl-perl-1.26-2.fc26.s390x
usbredir-0.7.1-3.fc26.s390x
fftw-libs-double-3.3.5-4.fc26.s390x
libiscsi-1.15.0-3.fc26.s390x
ttmkfdir-3.0.9-49.fc26.s390x
texlive-base-2016-33.20160520.fc26.1.noarch
python2-six-1.10.0-9.fc26.noarch
atk-2.24.0-1.fc26.s390x
python2-kitchen-1.2.4-6.fc26.noarch
guile-2.0.14-1.fc26.s390x
desktop-file-utils-0.23-3.fc26.s390x
pyxattr-0.5.3-10.fc26.s390x
shared-mime-info-1.8-2.fc26.s390x
libyaml-0.1.7-2.fc26.s390x
python3-PyYAML-3.12-3.fc26.s390x
openssh-7.5p1-4.fc26.s390x
kernel-core-4.13.16-202.fc26.s390x
perl-Git-2.13.6-2.fc26.noarch
openssl-1.1.0g-1.fc26.s390x
gawk-4.1.4-6.fc26.s390x
gnutls-3.5.16-4.fc26.s390x
openldap-2.4.45-2.fc26.s390x
NetworkManager-libnm-1.8.2-4.fc26.s390x
gnutls-devel-3.5.16-4.fc26.s390x
python2-urllib3-1.20-2.fc26.noarch
sssd-nfs-idmap-1.16.0-4.fc26.s390x
libsss_sudo-1.16.0-4.fc26.s390x
python3-py-1.4.34-1.fc26.noarch
perl-ExtUtils-Command-7.24-3.fc26.noarch
tzdata-2018c-1.fc26.noarch
libcrypt-nss-2.25-13.fc26.s390x
libstdc++-devel-7.3.1-2.fc26.s390x
rpcbind-0.2.4-8.rc3.fc26.s390x
gdb-headless-8.0.1-36.fc26.s390x
python3-dnf-plugins-extras-common-2.0.5-1.fc26.noarch
glibc-headers-2.25-13.fc26.s390x
libfdt-1.4.6-1.fc26.s390x
pcre-utf32-8.41-5.fc26.s390x
wget-1.19.4-1.fc26.s390x
mariadb-common-10.1.30-2.fc26.s390x
glusterfs-extra-xlators-3.10.10-1.fc26.s390x
python2-dnf-plugin-migrate-2.1.5-4.fc26.noarch
pcre2-devel-10.23-13.fc26.s390x
perl-threads-shared-1.58-1.fc26.s390x
gcc-c++-7.3.1-2.fc26.s390x
ImageMagick-libs-6.9.9.27-1.fc26.s390x
poppler-0.52.0-11.fc26.s390x
perl-Data-Dumper-2.161-4.fc26.s390x
python2-dnf-plugins-extras-common-2.0.5-1.fc26.noarch
gcc-debuginfo-7.3.1-2.fc26.s390x
libgudev-232-1.fc26.s390x
python3-javapackages-4.7.0-17.fc26.noarch
python3-ply-3.9-3.fc26.noarch
python3-systemd-234-1.fc26.s390x
python3-requests-2.13.0-1.fc26.noarch
blktrace-1.1.0-4.fc26.s390x
python2-asn1crypto-0.23.0-1.fc26.noarch
python2-cffi-1.9.1-2.fc26.s390x
python2-sphinx_rtd_theme-0.2.4-1.fc26.noarch
lua-json-1.3.2-7.fc26.noarch
libcephfs1-10.2.7-2.fc26.s390x
glib-networking-2.50.0-2.fc26.s390x
elfutils-default-yama-scope-0.169-1.fc26.noarch
libedit-3.1-17.20160618cvs.fc26.s390x
libverto-libev-0.2.6-7.fc26.s390x
libserf-1.3.9-3.fc26.s390x
python2-kerberos-1.2.5-3.fc26.s390x
libsrtp-1.5.4-4.fc26.s390x
lzo-minilzo-2.08-9.fc26.s390x
librepo-1.8.0-1.fc26.s390x
koji-1.14.0-1.fc26.noarch
sg3_utils-1.42-1.fc26.s390x
policycoreutils-2.6-6.fc26.s390x
systemtap-client-3.2-2.fc26.s390x
lvm2-2.02.168-6.fc26.s390x
device-mapper-multipath-libs-0.4.9-88.fc26.s390x
s390utils-cmsfs-1.36.1-3.fc26.s390x
libXdamage-1.1.4-9.fc26.s390x
libXaw-1.0.13-5.fc26.s390x
brltty-5.5-5.fc26.s390x
librsvg2-2.40.18-1.fc26.s390x
texlive-tetex-bin-svn36770.0-33.20160520.fc26.2.noarch
texlive-etex-pkg-svn39355-33.fc26.2.noarch
texlive-graphics-svn41015-33.fc26.2.noarch
texlive-dvips-svn41149-33.fc26.2.noarch
texlive-zapfding-svn31835.0-33.fc26.2.noarch
texlive-footmisc-svn23330.5.5b-33.fc26.2.noarch
texlive-makeindex-svn40768-33.fc26.2.noarch
texlive-pst-ovl-svn40873-33.fc26.2.noarch
texlive-texlive-scripts-svn41433-33.fc26.2.noarch
texlive-ltabptch-svn17533.1.74d-33.fc26.2.noarch
texlive-euro-svn22191.1.1-33.fc26.2.noarch
texlive-mflogo-font-svn36898.1.002-33.fc26.2.noarch
texlive-zapfchan-svn31835.0-33.fc26.2.noarch
texlive-cmextra-svn32831.0-33.fc26.2.noarch
texlive-finstrut-svn21719.0.5-33.fc26.2.noarch
texlive-hyphen-base-svn41138-33.fc26.2.noarch
texlive-marginnote-svn41382-33.fc26.2.noarch
texlive-parallel-svn15878.0-33.fc26.2.noarch
texlive-sepnum-svn20186.2.0-33.fc26.2.noarch
texlive-environ-svn33821.0.3-33.fc26.2.noarch
texlive-type1cm-svn21820.0-33.fc26.2.noarch
texlive-xunicode-svn30466.0.981-33.fc26.2.noarch
texlive-attachfile-svn38830-33.fc26.2.noarch
texlive-fontspec-svn41262-33.fc26.2.noarch
texlive-fancyvrb-svn18492.2.8-33.fc26.2.noarch
texlive-pst-pdf-bin-svn7838.0-33.20160520.fc26.2.noarch
texlive-xcolor-svn41044-33.fc26.2.noarch
texlive-pdfpages-svn40638-33.fc26.2.noarch
texlive-sansmathaccent-svn30187.0-33.fc26.2.noarch
texlive-ucs-svn35853.2.2-33.fc26.2.noarch
texlive-dvipdfmx-bin-svn40273-33.20160520.fc26.2.s390x
libotf-0.9.13-8.fc26.s390x
go-srpm-macros-2-8.fc26.noarch
mesa-libwayland-egl-devel-17.2.4-2.fc26.s390x
ghostscript-9.20-10.fc26.s390x
libcephfs_jni-devel-10.2.7-2.fc26.s390x
libXdamage-devel-1.1.4-9.fc26.s390x
freetype-devel-2.7.1-9.fc26.s390x
ncurses-devel-6.0-8.20170212.fc26.s390x
fontconfig-devel-2.12.6-4.fc26.s390x
cairo-devel-1.14.10-1.fc26.s390x
libselinux-devel-2.6-7.fc26.s390x
guile-devel-2.0.14-1.fc26.s390x
libcap-ng-devel-0.7.8-3.fc26.s390x
bash-completion-2.6-1.fc26.noarch
libXevie-1.0.3-12.fc26.s390x
python-firewall-0.4.4.5-1.fc26.noarch
python3-html5lib-0.999-13.fc26.noarch
python2-simplejson-3.10.0-3.fc26.s390x
flex-2.6.1-3.fc26.s390x
telnet-0.17-69.fc26.s390x
gpg-pubkey-8e1431d5-53bcbac7
emacs-filesystem-25.3-3.fc26.noarch
fontawesome-fonts-4.7.0-2.fc26.noarch
fontawesome-fonts-web-4.7.0-2.fc26.noarch
rpmconf-base-1.0.19-1.fc26.noarch
info-6.3-3.fc26.s390x
sqlite-libs-3.20.1-1.fc26.s390x
texlive-lib-2016-33.20160520.fc26.1.s390x
libicu-57.1-7.fc26.s390x
libcap-ng-0.7.8-3.fc26.s390x
nettle-3.3-2.fc26.s390x
libidn2-2.0.4-1.fc26.s390x
lcms2-2.8-3.fc26.s390x
dbus-libs-1.11.18-1.fc26.s390x
perl-Exporter-5.72-367.fc26.noarch
unzip-6.0-34.fc26.s390x
iproute-4.11.0-1.fc26.s390x
zip-3.0-18.fc26.s390x
perl-constant-1.33-368.fc26.noarch
perl-MIME-Base64-3.15-366.fc26.s390x
lua-posix-33.3.1-4.fc26.s390x
bzip2-1.0.6-22.fc26.s390x
hyphen-2.8.8-6.fc26.s390x
libdvdread-5.0.3-4.fc26.s390x
libcollection-0.7.0-34.fc26.s390x
libdvdnav-5.0.3-5.fc26.s390x
perl-version-0.99.18-1.fc26.s390x
perl-Encode-2.88-6.fc26.s390x
automake-1.15-9.fc26.noarch
plymouth-core-libs-0.9.3-0.7.20160620git0e65b86c.fc26.s390x
hesiod-3.2.1-7.fc26.s390x
jasper-libs-2.0.14-1.fc26.s390x
mozjs17-17.0.0-18.fc26.s390x
fontconfig-2.12.6-4.fc26.s390x
harfbuzz-1.4.4-1.fc26.s390x
alsa-lib-1.1.4.1-1.fc26.s390x
make-4.2.1-2.fc26.s390x
gobject-introspection-1.52.1-1.fc26.s390x
hicolor-icon-theme-0.15-5.fc26.noarch
gdk-pixbuf2-2.36.9-1.fc26.s390x
libgusb-0.2.11-1.fc26.s390x
libdhash-0.5.0-34.fc26.s390x
python2-bcrypt-3.1.4-2.fc26.s390x
PyYAML-3.12-3.fc26.s390x
nss-softokn-freebl-3.34.0-1.0.fc26.s390x
kernel-modules-4.13.16-202.fc26.s390x
git-2.13.6-2.fc26.s390x
openssl-devel-1.1.0g-1.fc26.s390x
copy-jdk-configs-3.3-2.fc26.noarch
python3-setuptools-37.0.0-1.fc26.noarch
kernel-core-4.14.8-200.fc26.s390x
NetworkManager-1.8.2-4.fc26.s390x
libjpeg-turbo-devel-1.5.3-1.fc26.s390x
lua-5.3.4-7.fc26.s390x
boost-thread-1.63.0-10.fc26.s390x
libwebp-0.6.1-1.fc26.s390x
kernel-devel-4.14.8-200.fc26.s390x
perl-autodie-2.29-367.fc26.noarch
tzdata-java-2018c-1.fc26.noarch
glusterfs-3.10.10-1.fc26.s390x
glusterfs-api-3.10.10-1.fc26.s390x
pcre-8.41-5.fc26.s390x
createrepo_c-0.10.0-15.fc26.s390x
mock-core-configs-28.2-1.fc26.noarch
libgfortran-7.3.1-2.fc26.s390x
libdrm-2.4.89-1.fc26.s390x
pcre-utf16-8.41-5.fc26.s390x
vim-common-8.0.1438-1.fc26.s390x
mariadb-config-10.1.30-2.fc26.s390x
python2-gluster-3.10.10-1.fc26.s390x
java-1.8.0-openjdk-1.8.0.161-5.b14.fc26.s390x
libtasn1-devel-4.13-1.fc26.s390x
vim-enhanced-8.0.1438-1.fc26.s390x
gcc-gdb-plugin-7.3.1-2.fc26.s390x
gnupg2-smime-2.2.4-1.fc26.s390x
python2-libxml2-2.9.7-1.fc26.s390x
net-tools-2.0-0.44.20160912git.fc26.s390x
python2-requests-kerberos-0.12.0-1.fc26.noarch
gcc-base-debuginfo-7.3.1-2.fc26.s390x
python3-lxml-4.1.1-1.fc26.s390x
python3-ordered-set-2.0.0-6.fc26.noarch
python3-rpmconf-1.0.19-1.fc26.noarch
python-offtrac-0.1.0-9.fc26.noarch
python2-pycparser-2.14-10.fc26.noarch
python2-sphinx-theme-alabaster-0.7.9-3.fc26.noarch
python2-pysocks-1.6.7-1.fc26.noarch
lua-lpeg-1.0.1-2.fc26.s390x
libproxy-0.4.15-2.fc26.s390x
crontabs-1.11-14.20150630git.fc26.noarch
libev-4.24-2.fc26.s390x
libsigsegv-2.11-1.fc26.s390x
fedora-cert-0.6.0.1-2.fc26.noarch
drpm-0.3.0-6.fc26.s390x
python2-cccolutils-1.5-3.fc26.s390x
m17n-lib-1.7.0-6.fc26.s390x
lsscsi-0.28-4.fc26.s390x
python2-koji-1.14.0-1.fc26.noarch
python3-koji-1.14.0-1.fc26.noarch
python3-gpg-1.8.0-12.fc26.s390x
sg3_utils-libs-1.42-1.fc26.s390x
SDL2-2.0.7-2.fc26.s390x
util-linux-2.30.2-1.fc26.s390x
s390utils-mon_statd-1.36.1-3.fc26.s390x
GConf2-3.2.6-17.fc26.s390x
systemd-container-233-7.fc26.s390x
usermode-1.111-9.fc26.s390x
libXt-1.1.5-4.fc26.s390x
libXpm-3.5.12-2.fc26.s390x
at-spi2-core-2.24.1-1.fc26.s390x
cairo-1.14.10-1.fc26.s390x
texlive-kpathsea-bin-svn40473-33.20160520.fc26.2.s390x
texlive-ifluatex-svn41346-33.fc26.2.noarch
texlive-babel-svn40706-33.fc26.2.noarch
texlive-colortbl-svn29803.v1.0a-33.fc26.2.noarch
texlive-marvosym-svn29349.2.2a-33.fc26.2.noarch
texlive-euler-svn17261.2.5-33.fc26.2.noarch
texlive-latexconfig-svn40274-33.fc26.2.noarch
texlive-plain-svn40274-33.fc26.2.noarch
texlive-texconfig-bin-svn29741.0-33.20160520.fc26.2.noarch
giflib-4.1.6-16.fc26.s390x
texlive-microtype-svn41127-33.fc26.2.noarch
texlive-eurosym-svn17265.1.4_subrfix-33.fc26.2.noarch
texlive-symbol-svn31835.0-33.fc26.2.noarch
texlive-chngcntr-svn17157.1.0a-33.fc26.2.noarch
texlive-euenc-svn19795.0.1h-33.fc26.2.noarch
texlive-luatex-svn40963-33.fc26.2.noarch
texlive-knuth-local-svn38627-33.fc26.2.noarch
texlive-mparhack-svn15878.1.4-33.fc26.2.noarch
texlive-rcs-svn15878.0-33.fc26.2.noarch
texlive-texlive-msg-translations-svn41431-33.fc26.2.noarch
texlive-updmap-map-svn41159-33.fc26.2.noarch
texlive-geometry-svn19716.5.6-33.fc26.2.noarch
texlive-memoir-svn41203-33.fc26.2.noarch
texlive-l3kernel-svn41246-33.fc26.2.noarch
texlive-pst-eps-svn15878.1.0-33.fc26.2.noarch
texlive-pst-text-svn15878.1.00-33.fc26.2.noarch
texlive-amscls-svn36804.0-33.fc26.2.noarch
texlive-pst-slpe-svn24391.1.31-33.fc26.2.noarch
texlive-extsizes-svn17263.1.4a-33.fc26.2.noarch
texlive-xetex-def-svn40327-33.fc26.2.noarch
texlive-collection-latex-svn41011-33.20160520.fc26.2.noarch
gstreamer1-plugins-base-1.12.3-1.fc26.s390x
fpc-srpm-macros-1.1-2.fc26.noarch
xorg-x11-proto-devel-7.7-22.fc26.noarch
urw-fonts-2.4-23.fc26.noarch
atk-devel-2.24.0-1.fc26.s390x
libxcb-devel-1.12-3.fc26.s390x
libXrandr-devel-1.5.1-2.fc26.s390x
libcom_err-devel-1.43.4-2.fc26.s390x
dbus-devel-1.11.18-1.fc26.s390x
libepoxy-devel-1.4.3-1.fc26.s390x
libicu-devel-57.1-7.fc26.s390x
p11-kit-devel-0.23.9-2.fc26.s390x
rpm-build-4.13.0.2-1.fc26.s390x
libssh2-devel-1.8.0-5.fc26.s390x
graphviz-2.40.1-4.fc26.s390x
zlib-static-1.2.11-2.fc26.s390x
mesa-libgbm-devel-17.2.4-2.fc26.s390x
screen-4.6.2-1.fc26.s390x
python-osbs-client-0.39.1-1.fc26.noarch
pyparsing-2.1.10-3.fc26.noarch
python3-pyasn1-0.2.3-1.fc26.noarch
python2-html5lib-0.999-13.fc26.noarch
teamd-1.27-1.fc26.s390x
hardlink-1.3-1.fc26.s390x
chrpath-0.16-4.fc26.s390x
texlive-pdftex-doc-svn41149-33.fc26.2.noarch
nspr-4.17.0-1.fc26.s390x
grep-3.1-1.fc26.s390x
libacl-2.2.52-15.fc26.s390x
cpio-2.12-4.fc26.s390x
libatomic_ops-7.4.4-2.fc26.s390x
p11-kit-0.23.9-2.fc26.s390x
gc-7.6.0-2.fc26.s390x
psmisc-22.21-9.fc26.s390x
systemd-libs-233-7.fc26.s390x
xz-5.2.3-2.fc26.s390x
perl-libs-5.24.3-395.fc26.s390x
libpcap-1.8.1-3.fc26.s390x
perl-macros-5.24.3-395.fc26.s390x
perl-parent-0.236-2.fc26.noarch
perl-Text-Unidecode-1.30-2.fc26.noarch
newt-0.52.20-1.fc26.s390x
libcomps-0.1.8-3.fc26.s390x
libfontenc-1.1.3-4.fc26.s390x
ipcalc-0.2.0-1.fc26.s390x
libnfnetlink-1.0.1-9.fc26.s390x
libref_array-0.1.5-34.fc26.s390x
perl-Term-Cap-1.17-366.fc26.noarch
perl-Digest-1.17-367.fc26.noarch
perl-SelfLoader-1.23-395.fc26.noarch
perl-Pod-Simple-3.35-2.fc26.noarch
perl-URI-1.71-6.fc26.noarch
attr-2.4.47-18.fc26.s390x
gmp-c++-6.1.2-4.fc26.s390x
harfbuzz-icu-1.4.4-1.fc26.s390x
http-parser-2.7.1-5.fc26.s390x
libsodium-1.0.14-1.fc26.s390x
python-gssapi-1.2.0-5.fc26.s390x
nss-softokn-3.34.0-1.0.fc26.s390x
nss-devel-3.34.0-1.0.fc26.s390x
perl-libnet-3.11-1.fc26.noarch
kernel-devel-4.13.16-202.fc26.s390x
python2-libs-2.7.14-4.fc26.s390x
libwayland-client-1.13.0-3.fc26.s390x
python3-dnf-2.7.5-2.fc26.noarch
kernel-modules-4.14.8-200.fc26.s390x
NetworkManager-ppp-1.8.2-4.fc26.s390x
wayland-devel-1.13.0-3.fc26.s390x
kernel-4.14.8-200.fc26.s390x
boost-random-1.63.0-10.fc26.s390x
mailx-12.5-24.fc26.s390x
NetworkManager-glib-1.8.2-4.fc26.s390x
perl-IPC-System-Simple-1.25-12.fc26.noarch
vim-filesystem-8.0.1438-1.fc26.s390x
glusterfs-libs-3.10.10-1.fc26.s390x
sed-4.4-2.fc26.s390x
libassuan-2.5.1-1.fc26.s390x
createrepo_c-libs-0.10.0-15.fc26.s390x
dnf-utils-2.1.5-4.fc26.noarch
libobjc-7.3.1-2.fc26.s390x
dracut-046-8.git20180105.fc26.s390x
libseccomp-2.3.3-1.fc26.s390x
mock-1.4.8-1.fc26.noarch
python-sphinx-locale-1.5.6-1.fc26.noarch
pcre-devel-8.41-5.fc26.s390x
libxml2-devel-2.9.7-1.fc26.s390x
libseccomp-devel-2.3.3-1.fc26.s390x
fedora-upgrade-28.1-1.fc26.noarch
gcc-gfortran-7.3.1-2.fc26.s390x
gdb-8.0.1-36.fc26.s390x
unbound-libs-1.6.8-1.fc26.s390x
man-db-2.7.6.1-9.fc26.s390x
python2-rpm-macros-3-21.fc26.noarch
kernel-devel-4.15.4-200.fc26.s390x
libcroco-0.6.12-1.fc26.s390x
libssh2-1.8.0-5.fc26.s390x
json-glib-1.2.6-1.fc26.s390x
libevent-2.0.22-3.fc26.s390x
gdk-pixbuf2-modules-2.36.9-1.fc26.s390x
colord-libs-1.3.5-1.fc26.s390x
python3-magic-5.30-11.fc26.noarch
python3-gobject-base-3.24.1-1.fc26.s390x
python3-pyroute2-0.4.13-1.fc26.noarch
python3-pysocks-1.6.7-1.fc26.noarch
python2-click-6.7-3.fc26.noarch
python-munch-2.1.0-2.fc26.noarch
python2-ply-3.9-3.fc26.noarch
python2-snowballstemmer-1.2.1-3.fc26.noarch
python-magic-5.30-11.fc26.noarch
python-beautifulsoup4-4.6.0-1.fc26.noarch
python2-gitdb-2.0.3-1.fc26.noarch
librados-devel-10.2.7-2.fc26.s390x
libcacard-2.5.3-1.fc26.s390x
libmodman-2.0.1-13.fc26.s390x
zziplib-0.13.62-8.fc26.s390x
lksctp-tools-1.0.16-6.fc26.s390x
procmail-3.22-44.fc26.s390x
libthai-0.1.25-2.fc26.s390x
libpipeline-1.4.1-3.fc26.s390x
python2-pycurl-7.43.0-8.fc26.s390x
deltarpm-3.6-19.fc26.s390x
subversion-libs-1.9.7-1.fc26.s390x
python-krbV-1.0.90-13.fc26.s390x
m17n-db-1.7.0-8.fc26.noarch
linux-atm-libs-2.5.1-17.fc26.s390x
python2-rpm-4.13.0.2-1.fc26.s390x
python2-librepo-1.8.0-1.fc26.s390x
qrencode-libs-3.4.4-1.fc26.s390x
s390utils-iucvterm-1.36.1-3.fc26.s390x
libsmartcols-2.30.2-1.fc26.s390x
dbus-1.11.18-1.fc26.s390x
systemd-udev-233-7.fc26.s390x
device-mapper-event-1.02.137-6.fc26.s390x
polkit-0.113-8.fc26.s390x
libwmf-lite-0.2.8.4-53.fc26.s390x
libXcomposite-0.4.4-9.fc26.s390x
libXcursor-1.1.14-8.fc26.s390x
at-spi2-atk-2.24.1-1.fc26.s390x
pango-1.40.12-1.fc26.s390x
texlive-metafont-bin-svn40987-33.20160520.fc26.2.s390x
texlive-url-svn32528.3.4-33.fc26.2.noarch
texlive-fp-svn15878.0-33.fc26.2.noarch
texlive-latex-fonts-svn28888.0-33.fc26.2.noarch
texlive-mptopdf-bin-svn18674.0-33.20160520.fc26.2.noarch
texlive-fancybox-svn18304.1.4-33.fc26.2.noarch
texlive-lua-alt-getopt-svn29349.0.7.0-33.fc26.2.noarch
texlive-tex-bin-svn40987-33.20160520.fc26.2.s390x
texlive-texconfig-svn40768-33.fc26.2.noarch
texlive-wasy2-ps-svn35830.0-33.fc26.2.noarch
texlive-psfrag-svn15878.3.04-33.fc26.2.noarch
texlive-helvetic-svn31835.0-33.fc26.2.noarch
texlive-times-svn35058.0-33.fc26.2.noarch
texlive-cite-svn36428.5.5-33.fc26.2.noarch
texlive-fancyhdr-svn15878.3.1-33.fc26.2.noarch
texlive-luatex-bin-svn41091-33.20160520.fc26.2.s390x
texlive-lm-math-svn36915.1.959-33.fc26.2.noarch
texlive-ntgclass-svn15878.2.1a-33.fc26.2.noarch
texlive-sansmath-svn17997.1.1-33.fc26.2.noarch
texlive-textcase-svn15878.0-33.fc26.2.noarch
texlive-unicode-data-svn39808-33.fc26.2.noarch
texlive-breakurl-svn29901.1.40-33.fc26.2.noarch
texlive-latex-svn40218-33.fc26.2.noarch
texlive-lualatex-math-svn40621-33.fc26.2.noarch
texlive-pst-coil-svn37377.1.07-33.fc26.2.noarch
texlive-pst-plot-svn41242-33.fc26.2.noarch
texlive-unicode-math-svn38462-33.fc26.2.noarch
texlive-pst-blur-svn15878.2.0-33.fc26.2.noarch
texlive-cm-super-svn15878.0-33.fc26.2.noarch
texlive-wasysym-svn15878.2.0-33.fc26.2.noarch
texlive-collection-fontsrecommended-svn35830.0-33.20160520.fc26.2.noarch
libXv-1.0.11-2.fc26.s390x
ghc-srpm-macros-1.4.2-5.fc26.noarch
latex2html-2017.2-2.fc26.noarch
libXau-devel-1.0.8-7.fc26.s390x
libXcursor-devel-1.1.14-8.fc26.s390x
graphite2-devel-1.3.10-1.fc26.s390x
pixman-devel-0.34.0-3.fc26.s390x
wayland-protocols-devel-1.9-1.fc26.noarch
mesa-libGLES-devel-17.2.4-2.fc26.s390x
vte291-devel-0.48.4-1.fc26.s390x
ceph-devel-compat-10.2.7-2.fc26.s390x
lzo-devel-2.08-9.fc26.s390x
libiscsi-devel-1.15.0-3.fc26.s390x
avahi-autoipd-0.6.32-7.fc26.s390x
rpm-plugin-systemd-inhibit-4.13.0.2-1.fc26.s390x
python2-ndg_httpsclient-0.4.0-7.fc26.noarch
gettext-0.19.8.1-9.fc26.s390x
btrfs-progs-4.9.1-2.fc26.s390x
fedora-logos-26.0.1-1.fc26.s390x
dejagnu-1.6-2.fc26.noarch
libaio-devel-0.3.110-7.fc26.s390x
dos2unix-7.3.4-2.fc26.s390x
popt-1.16-12.fc26.s390x
tar-1.29-5.fc26.s390x
avahi-libs-0.6.32-7.fc26.s390x
m4-1.4.18-3.fc26.s390x
perl-Time-Local-1.250-2.fc26.noarch
libmetalink-0.1.3-2.fc26.s390x
jbigkit-libs-2.1-6.fc26.s390x
netpbm-10.80.00-2.fc26.s390x
perl-Digest-MD5-2.55-3.fc26.s390x
perl-Getopt-Long-2.49.1-2.fc26.noarch
libglvnd-opengl-1.0.0-1.fc26.s390x
libattr-devel-2.4.47-18.fc26.s390x
teckit-2.5.1-16.fc26.s390x
python3-six-1.10.0-9.fc26.noarch
python3-libcomps-0.1.8-3.fc26.s390x
python3-pyparsing-2.1.10-3.fc26.noarch
python2-markupsafe-0.23-13.fc26.s390x
python2-mock-2.0.0-4.fc26.noarch
python2-yubico-1.3.2-7.fc26.noarch
python2-smmap-2.0.3-1.fc26.noarch
librbd-devel-10.2.7-2.fc26.s390x
libnghttp2-1.21.1-1.fc26.s390x
ykpers-1.18.0-2.fc26.s390x
python3-librepo-1.8.0-1.fc26.s390x
systemtap-runtime-3.2-2.fc26.s390x
geoclue2-2.4.5-4.fc26.s390x
initscripts-9.72-1.fc26.s390x
plymouth-0.9.3-0.7.20160620git0e65b86c.fc26.s390x
ebtables-2.0.10-22.fc26.s390x
gssproxy-0.7.0-9.fc26.s390x
libXext-1.3.3-5.fc26.s390x
mesa-libEGL-17.2.4-2.fc26.s390x
texlive-texlive.infra-bin-svn40312-33.20160520.fc26.2.s390x
texlive-thumbpdf-svn34621.3.16-33.fc26.2.noarch
texlive-carlisle-svn18258.0-33.fc26.2.noarch
texlive-gsftopk-svn40768-33.fc26.2.noarch
texlive-pdftex-svn41149-33.fc26.2.noarch
texlive-crop-svn15878.1.5-33.fc26.2.noarch
texlive-pxfonts-svn15878.0-33.fc26.2.noarch
texlive-enctex-svn34957.0-33.fc26.2.noarch
texlive-kastrup-svn15878.0-33.fc26.2.noarch
texlive-pspicture-svn15878.0-33.fc26.2.noarch
texlive-varwidth-svn24104.0.92-33.fc26.2.noarch
texlive-currfile-svn40725-33.fc26.2.noarch
texlive-pst-grad-svn15878.1.06-33.fc26.2.noarch
texlive-latex-bin-svn41438-33.fc26.2.noarch
texlive-ltxmisc-svn21927.0-33.fc26.2.noarch
lasi-1.1.2-7.fc26.s390x
adwaita-icon-theme-3.24.0-2.fc26.noarch
xz-devel-5.2.3-2.fc26.s390x
xorg-x11-fonts-Type1-7.5-17.fc26.noarch
libXi-devel-1.7.9-2.fc26.s390x
at-spi2-atk-devel-2.24.1-1.fc26.s390x
pango-devel-1.40.12-1.fc26.s390x
libcacard-devel-2.5.3-1.fc26.s390x
subversion-1.9.7-1.fc26.s390x
sudo-1.8.21p2-1.fc26.s390x
pykickstart-2.35-2.fc26.noarch
e2fsprogs-1.43.4-2.fc26.s390x
libbsd-0.8.3-3.fc26.s390x
c-ares-1.13.0-1.fc26.s390x
python2-pyxdg-0.25-12.fc26.noarch
nss-softokn-freebl-devel-3.34.0-1.0.fc26.s390x
strace-4.20-1.fc26.s390x
valgrind-3.13.0-12.fc26.s390x
libsss_idmap-1.16.0-4.fc26.s390x
gnutls-c++-3.5.16-4.fc26.s390x
libwayland-server-1.13.0-3.fc26.s390x
dhcp-client-4.3.5-10.fc26.s390x
man-pages-4.09-4.fc26.noarch
libffi-devel-3.1-12.fc26.s390x
libxml2-2.9.7-1.fc26.s390x
kmod-25-1.fc26.s390x
dnf-plugins-core-2.1.5-4.fc26.noarch
kmod-libs-25-1.fc26.s390x
pigz-2.4-1.fc26.s390x
pkgconf-pkg-config-1.3.12-2.fc26.s390x
libdrm-devel-2.4.89-1.fc26.s390x
gcc-go-7.3.1-2.fc26.s390x
system-python-3.6.4-2.fc26.s390x
python-rpm-macros-3-21.fc26.noarch
gpg-pubkey-a29cb19c-53bcbba6
quota-nls-4.03-9.fc26.noarch
xz-libs-5.2.3-2.fc26.s390x
gmp-6.1.2-4.fc26.s390x
file-5.30-11.fc26.s390x
libusbx-1.0.21-2.fc26.s390x
binutils-2.27-28.fc26.s390x
perl-Errno-1.25-395.fc26.s390x
perl-HTTP-Tiny-0.070-2.fc26.noarch
xml-common-0.6.3-45.fc26.noarch
opus-1.2.1-1.fc26.s390x
flac-libs-1.3.2-2.fc26.s390x
libacl-devel-2.2.52-15.fc26.s390x
coreutils-common-8.27-7.fc26.s390x
cracklib-2.9.6-5.fc26.s390x
pyliblzma-0.5.3-17.fc26.s390x
libnotify-0.7.7-2.fc26.s390x
python3-idna-2.5-1.fc26.noarch
python3-pyOpenSSL-16.2.0-6.fc26.noarch
python2-pbr-1.10.0-4.fc26.noarch
pyusb-1.0.0-4.fc26.noarch
librbd1-10.2.7-2.fc26.s390x
libnfs-1.9.8-3.fc26.s390x
libsolv-0.6.30-2.fc26.s390x
python3-pycurl-7.43.0-8.fc26.s390x
libyubikey-1.13-3.fc26.s390x
rpmlint-1.10-5.fc26.noarch
python2-pygpgme-0.3-22.fc26.s390x
s390utils-base-1.36.1-3.fc26.s390x
ppp-2.4.7-11.fc26.s390x
s390utils-cpuplugd-1.36.1-3.fc26.s390x
libXrender-0.9.10-2.fc26.s390x
libglvnd-gles-1.0.0-1.fc26.s390x
texlive-texlive.infra-svn41280-33.fc26.2.noarch
texlive-lm-svn28119.2.004-33.fc26.2.noarch
texlive-babelbib-svn25245.1.31-33.fc26.2.noarch
texlive-index-svn24099.4.1beta-33.fc26.2.noarch
texlive-pdftex-bin-svn40987-33.20160520.fc26.2.s390x
texlive-csquotes-svn39538-33.fc26.2.noarch
texlive-rsfs-svn15878.0-33.fc26.2.noarch
texlive-etex-svn37057.0-33.fc26.2.noarch
texlive-knuth-lib-svn35820.0-33.fc26.2.noarch
texlive-pst-math-svn34786.0.63-33.fc26.2.noarch
texlive-utopia-svn15878.0-33.fc26.2.noarch
texlive-eso-pic-svn37925.2.0g-33.fc26.2.noarch
texlive-pst-fill-svn15878.1.01-33.fc26.2.noarch
texlive-latex-bin-bin-svn14050.0-33.20160520.fc26.2.noarch
texlive-jknapltx-svn19440.0-33.fc26.2.noarch
texlive-collection-latexrecommended-svn35765.0-33.20160520.fc26.2.noarch
adwaita-cursor-theme-3.24.0-2.fc26.noarch
xorg-x11-fonts-ISO8859-1-100dpi-7.5-17.fc26.noarch
libXcomposite-devel-0.4.4-9.fc26.s390x
at-spi2-core-devel-2.24.1-1.fc26.s390x
harfbuzz-devel-1.4.4-1.fc26.s390x
rpmdevtools-8.10-2.fc26.noarch
texi2html-5.0-5.fc26.noarch
libnfs-devel-1.9.8-3.fc26.s390x
firewalld-0.4.4.5-1.fc26.noarch
wpa_supplicant-2.6-12.fc26.s390x
systemtap-sdt-devel-3.2-2.fc26.s390x
newt-python-0.52.20-1.fc26.s390x
perl-Mozilla-CA-20160104-4.fc26.noarch
pth-2.0.7-28.fc26.s390x
python3-pyxdg-0.25-12.fc26.noarch
nss-softokn-devel-3.34.0-1.0.fc26.s390x
timedatex-0.4-3.fc26.s390x
libjpeg-turbo-1.5.3-1.fc26.s390x
libsss_nss_idmap-1.16.0-4.fc26.s390x
dnf-yum-2.7.5-2.fc26.noarch
libuv-devel-1.11.0-1.fc26.s390x
libstdc++-7.3.1-2.fc26.s390x
libgo-7.3.1-2.fc26.s390x
python3-dnf-plugins-core-2.1.5-4.fc26.noarch
gtk3-3.22.21-3.fc26.s390x
perl-threads-2.21-1.fc26.s390x
pkgconf-m4-1.3.12-2.fc26.noarch
gtk3-devel-3.22.21-3.fc26.s390x
gcc-objc-7.3.1-2.fc26.s390x
curl-7.53.1-14.fc26.s390x
vim-minimal-8.0.1438-1.fc26.s390x
python-async-0.6.1-9.fc22.s390x
poppler-data-0.4.7-7.fc26.noarch
ocaml-srpm-macros-4-2.fc26.noarch
libuuid-2.30.2-1.fc26.s390x
libgpg-error-1.25-2.fc26.s390x
graphite2-1.3.10-1.fc26.s390x
perl-Text-Tabs+Wrap-2013.0523-366.fc26.noarch
perl-Error-0.17024-8.fc26.noarch
which-2.21-2.fc26.s390x
libXau-1.0.8-7.fc26.s390x
orc-0.4.27-1.fc26.s390x
perl-Pod-Perldoc-3.28-1.fc26.noarch
libsndfile-1.0.28-6.fc26.s390x
patch-2.7.5-4.fc26.s390x
gzip-1.8-2.fc26.s390x
python-ipaddress-1.0.16-4.fc26.noarch
yum-metadata-parser-1.1.4-18.fc26.s390x
python3-dbus-1.2.4-6.fc26.s390x
python3-cryptography-2.0.2-2.fc26.s390x
python3-kickstart-2.35-2.fc26.noarch
python2-imagesize-0.7.1-5.fc26.noarch
python2-jinja2-2.9.6-1.fc26.noarch
libradosstriper-devel-10.2.7-2.fc26.s390x
soundtouch-1.9.2-4.fc26.s390x
libndp-1.6-2.fc26.s390x
rpm-4.13.0.2-1.fc26.s390x
rest-0.8.0-2.fc26.s390x
libvisual-0.4.0-21.fc26.s390x
python2-hawkey-0.11.1-1.fc26.s390x
fakeroot-libs-1.22-1.fc26.s390x
device-mapper-event-libs-1.02.137-6.fc26.s390x
cyrus-sasl-2.1.26-32.fc26.s390x
cronie-anacron-1.5.1-5.fc26.s390x
libpath_utils-0.2.1-34.fc26.s390x
libX11-common-1.6.5-2.fc26.noarch
libXft-2.3.2-5.fc26.s390x
gtk2-2.24.31-4.fc26.s390x
texlive-etoolbox-svn38031.2.2a-33.fc26.2.noarch
texlive-multido-svn18302.1.42-33.fc26.2.noarch
texlive-glyphlist-svn28576.0-33.fc26.2.noarch
texlive-setspace-svn24881.6.7a-33.fc26.2.noarch
texlive-mathtools-svn38833-33.fc26.2.noarch
texlive-ncntrsbk-svn31835.0-33.fc26.2.noarch
texlive-dvisvgm-def-svn41011-33.fc26.2.noarch
texlive-ifetex-svn24853.1.2-33.fc26.2.noarch
texlive-parskip-svn19963.2.0-33.fc26.2.noarch
texlive-bera-svn20031.0-33.fc26.2.noarch
texlive-pgf-svn40966-33.fc26.2.noarch
texlive-auto-pst-pdf-svn23723.0.6-33.fc26.2.noarch
texlive-ctable-svn38672-33.fc26.2.noarch
texlive-typehtml-svn17134.0-33.fc26.2.noarch
mesa-libGLES-17.2.4-2.fc26.s390x
vte291-0.48.4-1.fc26.s390x
libcephfs_jni1-10.2.7-2.fc26.s390x
bzip2-devel-1.0.6-22.fc26.s390x
expat-devel-2.2.4-1.fc26.s390x
libsepol-devel-2.6-2.fc26.s390x
glib2-static-2.52.3-2.fc26.s390x
virglrenderer-devel-0.6.0-1.20170210git76b3da97b.fc26.s390x
parted-3.2-24.fc26.s390x
python3-beautifulsoup4-4.6.0-1.fc26.noarch
python-bunch-1.0.1-10.fc26.noarch
lz4-1.8.0-1.fc26.s390x
nss-util-3.34.0-1.0.fc26.s390x
openssh-clients-7.5p1-4.fc26.s390x
chrony-3.2-1.fc26.s390x
dnf-conf-2.7.5-2.fc26.noarch
sssd-client-1.16.0-4.fc26.s390x
bodhi-client-2.12.2-3.fc26.noarch
libuv-1.11.0-1.fc26.s390x
glibc-2.25-13.fc26.s390x
libgomp-7.3.1-2.fc26.s390x
cmake-rpm-macros-3.10.1-11.fc26.noarch
gtk-update-icon-cache-3.22.21-3.fc26.s390x
pcre2-utf32-10.23-13.fc26.s390x
kernel-modules-4.15.4-200.fc26.s390x
libcurl-devel-7.53.1-14.fc26.s390x
webkitgtk4-2.18.6-1.fc26.s390x
libstdc++-static-7.3.1-2.fc26.s390x
rsync-3.1.3-2.fc26.s390x
hawkey-0.6.4-3.fc25.s390x
perl-srpm-macros-1-21.fc26.noarch
expat-2.2.4-1.fc26.s390x
chkconfig-1.10-1.fc26.s390x
findutils-4.6.0-12.fc26.s390x
mesa-libwayland-egl-17.2.4-2.fc26.s390x
procps-ng-3.3.10-13.fc26.s390x
mesa-libglapi-17.2.4-2.fc26.s390x
perl-Unicode-Normalize-1.25-366.fc26.s390x
perl-IO-Socket-IP-0.39-1.fc26.noarch
hunspell-en-US-0.20140811.1-6.fc26.noarch
libxcb-1.12-3.fc26.s390x
perl-Pod-Escapes-1.07-366.fc26.noarch
perl-Pod-Usage-1.69-2.fc26.noarch
libtheora-1.1.1-15.fc26.s390x
tcp_wrappers-7.6-85.fc26.s390x
coreutils-8.27-7.fc26.s390x
libmount-2.30.2-1.fc26.s390x
python2-iniparse-0.4-24.fc26.noarch
python2-decorator-4.0.11-2.fc26.noarch
ModemManager-glib-1.6.10-1.fc26.s390x
python3-decorator-4.0.11-2.fc26.noarch
python3-cffi-1.9.1-2.fc26.s390x
python-bugzilla-cli-2.1.0-1.fc26.noarch
python2-funcsigs-1.0.2-5.fc26.noarch
python2-babel-2.3.4-5.fc26.noarch
python-bugzilla-2.1.0-1.fc26.noarch
libradosstriper1-10.2.7-2.fc26.s390x
snappy-1.1.4-3.fc26.s390x
libmpcdec-1.2.6-17.fc26.s390x
rpm-libs-4.13.0.2-1.fc26.s390x
python-urlgrabber-3.10.1-11.fc26.noarch
sysfsutils-2.1.0-20.fc26.s390x
python3-hawkey-0.11.1-1.fc26.s390x
ethtool-4.13-1.fc26.s390x
iputils-20161105-5.fc26.s390x
plymouth-scripts-0.9.3-0.7.20160620git0e65b86c.fc26.s390x
cronie-1.5.1-5.fc26.s390x
libini_config-1.3.1-34.fc26.s390x
libX11-1.6.5-2.fc26.s390x
libglvnd-egl-1.0.0-1.fc26.s390x
texlive-kpathsea-svn41139-33.fc26.2.noarch
texlive-thumbpdf-bin-svn6898.0-33.20160520.fc26.2.noarch
texlive-subfig-svn15878.1.3-33.fc26.2.noarch
texlive-gsftopk-bin-svn40473-33.20160520.fc26.2.s390x
texlive-tex-ini-files-svn40533-33.fc26.2.noarch
texlive-qstest-svn15878.0-33.fc26.2.noarch
texlive-palatino-svn31835.0-33.fc26.2.noarch
texlive-ec-svn25033.1.0-33.fc26.2.noarch
texlive-iftex-svn29654.0.2-33.fc26.2.noarch
texlive-pslatex-svn16416.0-33.fc26.2.noarch
texlive-algorithms-svn38085.0.1-33.fc26.2.noarch
texlive-filehook-svn24280.0.5d-33.fc26.2.noarch
texlive-pst-node-svn40743-33.fc26.2.noarch
texlive-rotating-svn16832.2.16b-33.fc26.2.noarch
texlive-seminar-svn34011.1.62-33.fc26.2.noarch
libuuid-devel-2.30.2-1.fc26.s390x
libXinerama-devel-1.1.3-7.fc26.s390x
emacs-common-25.3-3.fc26.s390x
fedora-packager-0.6.0.1-2.fc26.noarch
snappy-devel-1.1.4-3.fc26.s390x
authconfig-7.0.1-2.fc26.s390x
newt-python3-0.52.20-1.fc26.s390x
python-decoratortools-1.8-13.fc26.noarch
python-systemd-doc-234-1.fc26.s390x
openssl-libs-1.1.0g-1.fc26.s390x
git-core-2.13.6-2.fc26.s390x
libsss_certmap-1.16.0-4.fc26.s390x
lsof-4.89-5.fc26.s390x
glibc-all-langpacks-2.25-13.fc26.s390x
audit-libs-2.8.2-1.fc26.s390x
python3-3.6.4-2.fc26.s390x
gcc-7.3.1-2.fc26.s390x
pcre2-utf16-10.23-13.fc26.s390x
kernel-core-4.15.4-200.fc26.s390x
pcre-static-8.41-5.fc26.s390x
dracut-config-rescue-046-8.git20180105.fc26.s390x
webkitgtk4-plugin-process-gtk2-2.18.6-1.fc26.s390x
perl-Time-HiRes-1.9753-1.fc26.s390x
haveged-1.9.1-6.fc26.s390x
gpg-pubkey-a0a7badb-52844296
gpg-pubkey-e372e838-56fd7943
gpg-pubkey-3b921d09-57a87096
google-roboto-slab-fonts-1.100263-0.5.20150923git.fc26.noarch
libreport-filesystem-2.9.1-3.fc26.s390x
libcom_err-1.43.4-2.fc26.s390x
libffi-3.1-12.fc26.s390x
keyutils-libs-1.5.10-1.fc26.s390x
diffutils-3.5-3.fc26.s390x
apr-util-1.5.4-6.fc26.s390x
bluez-libs-5.46-6.fc26.s390x
libksba-1.3.5-3.fc26.s390x
ncurses-6.0-8.20170212.fc26.s390x
gsm-1.0.17-1.fc26.s390x
libteam-1.27-1.fc26.s390x
perl-Fedora-VSP-0.001-5.fc26.noarch
libusb-0.1.5-8.fc26.s390x
acl-2.2.52-15.fc26.s390x
dwz-0.12-3.fc26.s390x
libblkid-2.30.2-1.fc26.s390x
polkit-libs-0.113-8.fc26.s390x
dbus-python-1.2.4-6.fc26.s390x
gts-0.7.6-30.20121130.fc26.s390x
libfdisk-2.30.2-1.fc26.s390x
python3-pycparser-2.14-10.fc26.noarch
python3-bugzilla-2.1.0-1.fc26.noarch
python2-docutils-0.13.1-4.fc26.noarch
pytz-2016.10-4.fc26.noarch
python2-requests-2.13.0-1.fc26.noarch
libcephfs-devel-10.2.7-2.fc26.s390x
ncurses-c++-libs-6.0-8.20170212.fc26.s390x
GeoIP-1.6.11-1.fc26.s390x
liblockfile-1.09-5.fc26.s390x
rpm-plugin-selinux-4.13.0.2-1.fc26.s390x
systemtap-devel-3.2-2.fc26.s390x
libsysfs-2.1.0-20.fc26.s390x
libdnf-0.11.1-1.fc26.s390x
mesa-libgbm-17.2.4-2.fc26.s390x
lvm2-libs-2.02.168-6.fc26.s390x
libXfixes-5.0.3-2.fc26.s390x
brlapi-0.6.6-5.fc26.s390x
texlive-metafont-svn40793-33.fc26.2.noarch
texlive-graphics-cfg-svn40269-33.fc26.2.noarch
texlive-mptopdf-svn41282-33.fc26.2.noarch
texlive-makeindex-bin-svn40473-33.20160520.fc26.2.s390x
texlive-texlive-scripts-bin-svn29741.0-33.20160520.fc26.2.noarch
texlive-sauerj-svn15878.0-33.fc26.2.noarch
texlive-txfonts-svn15878.0-33.fc26.2.noarch
texlive-filecontents-svn24250.1.3-33.fc26.2.noarch
texlive-lualibs-svn40370-33.fc26.2.noarch
texlive-section-svn20180.0-33.fc26.2.noarch
texlive-ucharcat-svn38907-33.fc26.2.noarch
texlive-hyperref-svn41396-33.fc26.2.noarch
texlive-pst-3d-svn17257.1.10-33.fc26.2.noarch
texlive-oberdiek-svn41346-33.fc26.2.noarch
texlive-ae-svn15878.1.4-33.fc26.2.noarch
texlive-collection-basic-svn41149-33.20160520.fc26.2.noarch
gnat-srpm-macros-4-2.fc26.noarch
glib2-devel-2.52.3-2.fc26.s390x
netpbm-progs-10.80.00-2.fc26.s390x
libXxf86vm-devel-1.1.4-4.fc26.s390x
nettle-devel-3.3-2.fc26.s390x
cairo-gobject-devel-1.14.10-1.fc26.s390x
fedora-rpm-macros-26-2.fc26.noarch
elfutils-devel-0.169-1.fc26.s390x
libidn-devel-1.33-2.fc26.s390x
s390utils-1.36.1-3.fc26.s390x
libtool-2.4.6-17.fc26.s390x
python3-cssselect-0.9.2-4.fc26.noarch
python2-cssselect-0.9.2-4.fc26.noarch
bison-3.0.4-6.fc26.s390x
rootfiles-8.1-20.fc26.noarch
git-core-doc-2.13.6-2.fc26.s390x
boost-system-1.63.0-10.fc26.s390x
gnutls-dane-3.5.16-4.fc26.s390x
python3-urllib3-1.20-2.fc26.noarch
libsss_autofs-1.16.0-4.fc26.s390x
libgcc-7.3.1-2.fc26.s390x
system-python-libs-3.6.4-2.fc26.s390x
pcre-cpp-8.41-5.fc26.s390x
python3-distro-1.2.0-1.fc26.noarch
libnfsidmap-2.2.1-4.rc2.fc26.s390x
selinux-policy-3.13.1-260.18.fc26.noarch
glusterfs-devel-3.10.10-1.fc26.s390x
kernel-4.15.4-200.fc26.s390x
glibc-static-2.25-13.fc26.s390x
xapian-core-libs-1.4.5-1.fc26.s390x
publicsuffix-list-dafsa-20171228-1.fc26.noarch
=== TEST BEGIN ===
Using CC: /home/fam/bin/cc
Install prefix /var/tmp/patchew-tester-tmp-1tgugnof/src/install
BIOS directory /var/tmp/patchew-tester-tmp-1tgugnof/src/install/share/qemu
firmware path /var/tmp/patchew-tester-tmp-1tgugnof/src/install/share/qemu-firmware
binary directory /var/tmp/patchew-tester-tmp-1tgugnof/src/install/bin
library directory /var/tmp/patchew-tester-tmp-1tgugnof/src/install/lib
module directory /var/tmp/patchew-tester-tmp-1tgugnof/src/install/lib/qemu
libexec directory /var/tmp/patchew-tester-tmp-1tgugnof/src/install/libexec
include directory /var/tmp/patchew-tester-tmp-1tgugnof/src/install/include
config directory /var/tmp/patchew-tester-tmp-1tgugnof/src/install/etc
local state directory /var/tmp/patchew-tester-tmp-1tgugnof/src/install/var
Manual directory /var/tmp/patchew-tester-tmp-1tgugnof/src/install/share/man
ELF interp prefix /usr/gnemul/qemu-%M
Source path /var/tmp/patchew-tester-tmp-1tgugnof/src
GIT binary git
GIT submodules ui/keycodemapdb capstone
C compiler /home/fam/bin/cc
Host C compiler cc
C++ compiler c++
Objective-C compiler /home/fam/bin/cc
ARFLAGS rv
CFLAGS -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -g
QEMU_CFLAGS -I/usr/include/pixman-1 -Werror -DHAS_LIBSSH2_SFTP_FSYNC -pthread -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -m64 -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 -Wexpansion-to-defined -Wendif-labels -Wno-shift-negative-value -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-strong -I/usr/include/p11-kit-1 -I/usr/include/libpng16 -I/usr/include/libdrm -I$(SRC_PATH)/capstone/include
LDFLAGS -Wl,--warn-common -m64 -g
make make
install install
python python -B
smbd /usr/sbin/smbd
module support no
host CPU s390x
host big endian yes
target list aarch64-softmmu alpha-softmmu arm-softmmu cris-softmmu hppa-softmmu i386-softmmu lm32-softmmu m68k-softmmu microblazeel-softmmu microblaze-softmmu mips64el-softmmu mips64-softmmu mipsel-softmmu mips-softmmu moxie-softmmu nios2-softmmu or1k-softmmu ppc64-softmmu ppcemb-softmmu ppc-softmmu riscv32-softmmu riscv64-softmmu s390x-softmmu sh4eb-softmmu sh4-softmmu sparc64-softmmu sparc-softmmu tricore-softmmu unicore32-softmmu x86_64-softmmu xtensaeb-softmmu xtensa-softmmu aarch64_be-linux-user aarch64-linux-user alpha-linux-user armeb-linux-user arm-linux-user cris-linux-user hppa-linux-user i386-linux-user m68k-linux-user microblazeel-linux-user microblaze-linux-user mips64el-linux-user mips64-linux-user mipsel-linux-user mips-linux-user mipsn32el-linux-user mipsn32-linux-user nios2-linux-user or1k-linux-user ppc64abi32-linux-user ppc64le-linux-user ppc64-linux-user ppc-linux-user riscv32-linux-user riscv64-linux-user s390x-linux-user sh4eb-linux-user sh4-linux-user sparc32plus-linux-user sparc64-linux-user sparc-linux-user tilegx-linux-user x86_64-linux-user xtensaeb-linux-user xtensa-linux-user
gprof enabled no
sparse enabled no
strip binaries yes
profiler no
static build no
SDL support yes (2.0.7)
GTK support yes (3.22.21)
GTK GL support yes
VTE support yes (0.48.4)
TLS priority NORMAL
GNUTLS support yes
GNUTLS rnd yes
libgcrypt no
libgcrypt kdf no
nettle yes (3.3)
nettle kdf yes
libtasn1 yes
curses support yes
virgl support yes
curl support yes
mingw32 support no
Audio drivers oss
Block whitelist (rw)
Block whitelist (ro)
VirtFS support yes
Multipath support no
VNC support yes
VNC SASL support yes
VNC JPEG support yes
VNC PNG support yes
xen support no
brlapi support yes
bluez support yes
Documentation yes
PIE no
vde support no
netmap support no
Linux AIO support yes
ATTR/XATTR support yes
Install blobs yes
KVM support yes
HAX support no
HVF support no
WHPX support no
TCG support yes
TCG debug enabled no
TCG interpreter no
malloc trim support yes
RDMA support no
fdt support yes
membarrier no
preadv support yes
fdatasync yes
madvise yes
posix_madvise yes
posix_memalign yes
libcap-ng support yes
vhost-net support yes
vhost-crypto support yes
vhost-scsi support yes
vhost-vsock support yes
vhost-user support yes
Trace backends log
spice support no
rbd support yes
xfsctl support no
smartcard support yes
libusb yes
usb net redir yes
OpenGL support yes
OpenGL dmabufs yes
libiscsi support yes
libnfs support yes
build guest agent yes
QGA VSS support no
QGA w32 disk info no
QGA MSI support no
seccomp support yes
coroutine backend ucontext
coroutine pool yes
debug stack usage no
crypto afalg no
GlusterFS support yes
gcov gcov
gcov enabled no
TPM support yes
libssh2 support yes
TPM passthrough no
TPM emulator yes
QOM debugging yes
Live block migration yes
lzo support yes
snappy support yes
bzip2 support yes
NUMA host support no
libxml2 yes
tcmalloc support no
jemalloc support no
avx2 optimization no
replication support yes
VxHS block device no
capstone git
GEN aarch64-softmmu/config-devices.mak.tmp
GEN alpha-softmmu/config-devices.mak.tmp
GEN arm-softmmu/config-devices.mak.tmp
GEN cris-softmmu/config-devices.mak.tmp
GEN cris-softmmu/config-devices.mak
GEN hppa-softmmu/config-devices.mak.tmp
GEN arm-softmmu/config-devices.mak
GEN alpha-softmmu/config-devices.mak
GEN aarch64-softmmu/config-devices.mak
GEN i386-softmmu/config-devices.mak.tmp
GEN lm32-softmmu/config-devices.mak.tmp
GEN m68k-softmmu/config-devices.mak.tmp
GEN lm32-softmmu/config-devices.mak
GEN m68k-softmmu/config-devices.mak
GEN hppa-softmmu/config-devices.mak
GEN microblaze-softmmu/config-devices.mak.tmp
GEN microblazeel-softmmu/config-devices.mak.tmp
GEN mips64el-softmmu/config-devices.mak.tmp
GEN i386-softmmu/config-devices.mak
GEN mips64-softmmu/config-devices.mak.tmp
GEN microblaze-softmmu/config-devices.mak
GEN microblazeel-softmmu/config-devices.mak
GEN mipsel-softmmu/config-devices.mak.tmp
GEN mips-softmmu/config-devices.mak.tmp
GEN mips64el-softmmu/config-devices.mak
GEN moxie-softmmu/config-devices.mak.tmp
GEN mips64-softmmu/config-devices.mak
GEN nios2-softmmu/config-devices.mak.tmp
GEN mipsel-softmmu/config-devices.mak
GEN moxie-softmmu/config-devices.mak
GEN mips-softmmu/config-devices.mak
GEN nios2-softmmu/config-devices.mak
GEN or1k-softmmu/config-devices.mak.tmp
GEN ppc64-softmmu/config-devices.mak.tmp
GEN ppcemb-softmmu/config-devices.mak.tmp
GEN ppc-softmmu/config-devices.mak.tmp
GEN or1k-softmmu/config-devices.mak
GEN riscv32-softmmu/config-devices.mak.tmp
GEN ppc-softmmu/config-devices.mak
GEN ppc64-softmmu/config-devices.mak
GEN riscv64-softmmu/config-devices.mak.tmp
GEN ppcemb-softmmu/config-devices.mak
GEN riscv32-softmmu/config-devices.mak
GEN s390x-softmmu/config-devices.mak.tmp
GEN sh4eb-softmmu/config-devices.mak.tmp
GEN sh4-softmmu/config-devices.mak.tmp
GEN riscv64-softmmu/config-devices.mak
GEN sparc64-softmmu/config-devices.mak.tmp
GEN s390x-softmmu/config-devices.mak
GEN sh4-softmmu/config-devices.mak
GEN sparc-softmmu/config-devices.mak.tmp
GEN tricore-softmmu/config-devices.mak.tmp
GEN sh4eb-softmmu/config-devices.mak
GEN unicore32-softmmu/config-devices.mak.tmp
GEN sparc64-softmmu/config-devices.mak
GEN sparc-softmmu/config-devices.mak
GEN tricore-softmmu/config-devices.mak
GEN x86_64-softmmu/config-devices.mak.tmp
GEN xtensaeb-softmmu/config-devices.mak.tmp
GEN xtensa-softmmu/config-devices.mak.tmp
GEN unicore32-softmmu/config-devices.mak
GEN aarch64_be-linux-user/config-devices.mak.tmp
GEN xtensa-softmmu/config-devices.mak
GEN xtensaeb-softmmu/config-devices.mak
GEN x86_64-softmmu/config-devices.mak
GEN aarch64-linux-user/config-devices.mak.tmp
GEN aarch64_be-linux-user/config-devices.mak
GEN alpha-linux-user/config-devices.mak.tmp
GEN armeb-linux-user/config-devices.mak.tmp
GEN arm-linux-user/config-devices.mak.tmp
GEN armeb-linux-user/config-devices.mak
GEN alpha-linux-user/config-devices.mak
GEN aarch64-linux-user/config-devices.mak
GEN arm-linux-user/config-devices.mak
GEN cris-linux-user/config-devices.mak.tmp
GEN hppa-linux-user/config-devices.mak.tmp
GEN i386-linux-user/config-devices.mak.tmp
GEN m68k-linux-user/config-devices.mak.tmp
GEN cris-linux-user/config-devices.mak
GEN hppa-linux-user/config-devices.mak
GEN i386-linux-user/config-devices.mak
GEN m68k-linux-user/config-devices.mak
GEN microblazeel-linux-user/config-devices.mak.tmp
GEN microblaze-linux-user/config-devices.mak.tmp
GEN mips64el-linux-user/config-devices.mak.tmp
GEN mips64-linux-user/config-devices.mak.tmp
GEN microblaze-linux-user/config-devices.mak
GEN mips64el-linux-user/config-devices.mak
GEN microblazeel-linux-user/config-devices.mak
GEN mipsel-linux-user/config-devices.mak.tmp
GEN mips-linux-user/config-devices.mak.tmp
GEN mipsn32el-linux-user/config-devices.mak.tmp
GEN mips64-linux-user/config-devices.mak
GEN mipsn32-linux-user/config-devices.mak.tmp
GEN mipsn32el-linux-user/config-devices.mak
GEN mipsel-linux-user/config-devices.mak
GEN mips-linux-user/config-devices.mak
GEN nios2-linux-user/config-devices.mak.tmp
GEN or1k-linux-user/config-devices.mak.tmp
GEN mipsn32-linux-user/config-devices.mak
GEN ppc64abi32-linux-user/config-devices.mak.tmp
GEN ppc64le-linux-user/config-devices.mak.tmp
GEN nios2-linux-user/config-devices.mak
GEN or1k-linux-user/config-devices.mak
GEN ppc64-linux-user/config-devices.mak.tmp
GEN ppc64abi32-linux-user/config-devices.mak
GEN ppc-linux-user/config-devices.mak.tmp
GEN ppc64le-linux-user/config-devices.mak
GEN riscv32-linux-user/config-devices.mak.tmp
GEN riscv64-linux-user/config-devices.mak.tmp
GEN ppc64-linux-user/config-devices.mak
GEN ppc-linux-user/config-devices.mak
GEN s390x-linux-user/config-devices.mak.tmp
GEN sh4eb-linux-user/config-devices.mak.tmp
GEN riscv32-linux-user/config-devices.mak
GEN riscv64-linux-user/config-devices.mak
GEN s390x-linux-user/config-devices.mak
GEN sh4-linux-user/config-devices.mak.tmp
GEN sparc32plus-linux-user/config-devices.mak.tmp
GEN sparc64-linux-user/config-devices.mak.tmp
GEN sh4eb-linux-user/config-devices.mak
GEN sh4-linux-user/config-devices.mak
GEN sparc-linux-user/config-devices.mak.tmp
GEN sparc32plus-linux-user/config-devices.mak
GEN tilegx-linux-user/config-devices.mak.tmp
GEN sparc64-linux-user/config-devices.mak
GEN x86_64-linux-user/config-devices.mak.tmp
GEN xtensaeb-linux-user/config-devices.mak.tmp
GEN tilegx-linux-user/config-devices.mak
GEN sparc-linux-user/config-devices.mak
GEN xtensa-linux-user/config-devices.mak.tmp
GEN x86_64-linux-user/config-devices.mak
GEN xtensaeb-linux-user/config-devices.mak
GEN config-host.h
GIT ui/keycodemapdb capstone
GEN xtensa-linux-user/config-devices.mak
GEN qemu-options.def
GEN qapi-gen
GEN trace/generated-tcg-tracers.h
GEN trace/generated-helpers-wrappers.h
GEN trace/generated-helpers.h
GEN trace/generated-helpers.c
GEN module_block.h
GEN trace-root.h
GEN tests/test-qapi-gen
GEN util/trace.h
Submodule 'capstone' (git://git.qemu.org/capstone.git) registered for path 'capstone'
Submodule 'ui/keycodemapdb' (git://git.qemu.org/keycodemapdb.git) registered for path 'ui/keycodemapdb'
GEN crypto/trace.h
Cloning into '/var/tmp/patchew-tester-tmp-1tgugnof/src/capstone'...
GEN io/trace.h
GEN migration/trace.h
GEN block/trace.h
GEN chardev/trace.h
GEN hw/block/trace.h
GEN hw/block/dataplane/trace.h
GEN hw/char/trace.h
GEN hw/intc/trace.h
GEN hw/net/trace.h
GEN hw/rdma/trace.h
GEN hw/rdma/vmw/trace.h
GEN hw/virtio/trace.h
GEN hw/audio/trace.h
GEN hw/misc/trace.h
GEN hw/misc/macio/trace.h
GEN hw/usb/trace.h
GEN hw/scsi/trace.h
GEN hw/nvram/trace.h
GEN hw/display/trace.h
GEN hw/input/trace.h
GEN hw/timer/trace.h
GEN hw/dma/trace.h
GEN hw/sparc/trace.h
GEN hw/sparc64/trace.h
GEN hw/sd/trace.h
GEN hw/isa/trace.h
GEN hw/mem/trace.h
GEN hw/i386/trace.h
GEN hw/i386/xen/trace.h
GEN hw/9pfs/trace.h
GEN hw/ppc/trace.h
GEN hw/pci/trace.h
GEN hw/pci-host/trace.h
GEN hw/s390x/trace.h
GEN hw/vfio/trace.h
GEN hw/acpi/trace.h
GEN hw/arm/trace.h
GEN hw/alpha/trace.h
GEN hw/hppa/trace.h
GEN hw/xen/trace.h
GEN hw/ide/trace.h
GEN hw/tpm/trace.h
GEN ui/trace.h
GEN audio/trace.h
GEN net/trace.h
GEN target/arm/trace.h
GEN target/i386/trace.h
GEN target/mips/trace.h
GEN target/sparc/trace.h
GEN target/s390x/trace.h
GEN target/ppc/trace.h
GEN qom/trace.h
GEN linux-user/trace.h
GEN qapi/trace.h
GEN accel/tcg/trace.h
GEN accel/kvm/trace.h
GEN nbd/trace.h
GEN scsi/trace.h
GEN trace-root.c
GEN util/trace.c
GEN crypto/trace.c
GEN io/trace.c
GEN migration/trace.c
GEN block/trace.c
GEN chardev/trace.c
GEN hw/block/trace.c
GEN hw/block/dataplane/trace.c
GEN hw/char/trace.c
GEN hw/intc/trace.c
GEN hw/net/trace.c
GEN hw/rdma/trace.c
GEN hw/rdma/vmw/trace.c
GEN hw/virtio/trace.c
GEN hw/audio/trace.c
GEN hw/misc/trace.c
GEN hw/misc/macio/trace.c
GEN hw/usb/trace.c
GEN hw/scsi/trace.c
GEN hw/nvram/trace.c
GEN hw/display/trace.c
GEN hw/input/trace.c
GEN hw/timer/trace.c
GEN hw/dma/trace.c
GEN hw/sparc/trace.c
GEN hw/sparc64/trace.c
GEN hw/sd/trace.c
GEN hw/isa/trace.c
GEN hw/mem/trace.c
GEN hw/i386/trace.c
GEN hw/i386/xen/trace.c
GEN hw/9pfs/trace.c
GEN hw/ppc/trace.c
GEN hw/pci/trace.c
GEN hw/pci-host/trace.c
GEN hw/s390x/trace.c
GEN hw/vfio/trace.c
GEN hw/acpi/trace.c
GEN hw/arm/trace.c
GEN hw/alpha/trace.c
GEN hw/hppa/trace.c
GEN hw/xen/trace.c
GEN hw/ide/trace.c
GEN hw/tpm/trace.c
GEN ui/trace.c
GEN audio/trace.c
GEN net/trace.c
GEN target/arm/trace.c
GEN target/i386/trace.c
GEN target/mips/trace.c
GEN target/sparc/trace.c
GEN target/s390x/trace.c
GEN target/ppc/trace.c
GEN qom/trace.c
GEN linux-user/trace.c
GEN qapi/trace.c
GEN accel/tcg/trace.c
GEN accel/kvm/trace.c
GEN nbd/trace.c
GEN scsi/trace.c
GEN config-all-devices.mak
Cloning into '/var/tmp/patchew-tester-tmp-1tgugnof/src/ui/keycodemapdb'...
GEN ui/input-keymap-atset1-to-qcode.c
GEN ui/input-keymap-linux-to-qcode.c
GEN ui/input-keymap-qcode-to-atset1.c
GEN ui/input-keymap-qcode-to-atset2.c
GEN ui/input-keymap-qcode-to-atset3.c
GEN ui/input-keymap-qcode-to-linux.c
CC cs.o
GEN ui/input-keymap-qcode-to-qnum.c
GEN ui/input-keymap-qcode-to-sun.c
GEN ui/input-keymap-qnum-to-qcode.c
GEN ui/input-keymap-usb-to-qcode.c
GEN ui/input-keymap-win32-to-qcode.c
CC utils.o
GEN ui/input-keymap-x11-to-qcode.c
CC SStream.o
CC MCInstrDesc.o
CC MCRegisterInfo.o
GEN ui/input-keymap-xorgevdev-to-qcode.c
CC arch/ARM/ARMDisassembler.o
GEN ui/input-keymap-xorgkbd-to-qcode.c
GEN ui/input-keymap-xorgxquartz-to-qcode.c
GEN ui/input-keymap-xorgxwin-to-qcode.c
CC arch/ARM/ARMInstPrinter.o
CC arch/ARM/ARMMapping.o
CC arch/ARM/ARMModule.o
CC arch/AArch64/AArch64BaseInfo.o
CC arch/AArch64/AArch64Disassembler.o
CC arch/AArch64/AArch64InstPrinter.o
CC arch/AArch64/AArch64Mapping.o
CC arch/AArch64/AArch64Module.o
CC arch/Mips/MipsDisassembler.o
CC arch/Mips/MipsInstPrinter.o
CC arch/Mips/MipsMapping.o
CC arch/Mips/MipsModule.o
CC arch/PowerPC/PPCDisassembler.o
CC arch/PowerPC/PPCInstPrinter.o
CC arch/PowerPC/PPCMapping.o
CC arch/PowerPC/PPCModule.o
CC arch/Sparc/SparcDisassembler.o
CC arch/Sparc/SparcInstPrinter.o
CC arch/Sparc/SparcMapping.o
CC arch/Sparc/SparcModule.o
CC arch/SystemZ/SystemZDisassembler.o
CC arch/SystemZ/SystemZInstPrinter.o
CC arch/SystemZ/SystemZMapping.o
CC arch/SystemZ/SystemZModule.o
CC arch/SystemZ/SystemZMCTargetDesc.o
CC arch/X86/X86DisassemblerDecoder.o
CC arch/X86/X86Disassembler.o
CC arch/X86/X86IntelInstPrinter.o
CC arch/X86/X86ATTInstPrinter.o
CC arch/X86/X86Mapping.o
CC arch/X86/X86Module.o
CC arch/XCore/XCoreDisassembler.o
CC arch/XCore/XCoreInstPrinter.o
CC arch/XCore/XCoreMapping.o
CC arch/XCore/XCoreModule.o
CC MCInst.o
AR libcapstone.a
ar: creating /var/tmp/patchew-tester-tmp-1tgugnof/src/build/capstone/libcapstone.a
GEN docs/version.texi
GEN qemu-options.texi
CC tests/qemu-iotests/socket_scm_helper.o
GEN qemu-monitor.texi
GEN qemu-img-cmds.texi
GEN qemu-monitor-info.texi
GEN qemu-img.1
GEN qemu-nbd.8
GEN qemu-ga.8
GEN qga/qapi-generated/qapi-gen
GEN docs/qemu-block-drivers.7
GEN fsdev/virtfs-proxy-helper.1
CC qapi/qapi-builtin-types.o
CC qapi/qapi-types.o
CC qapi/qapi-types-block-core.o
CC qapi/qapi-types-block.o
In file included from /var/tmp/patchew-tester-tmp-1tgugnof/src/include/qapi/dealloc-visitor.h:17:0,
from qapi/qapi-builtin-types.c:14:
/var/tmp/patchew-tester-tmp-1tgugnof/src/include/qapi/visitor.h:243:5: error: unknown type name ‘QType’
QType type;
^~~~~
make: *** [/var/tmp/patchew-tester-tmp-1tgugnof/src/rules.mak:66: qapi/qapi-builtin-types.o] Error 1
make: *** Waiting for unfinished jobs....
In file included from /var/tmp/patchew-tester-tmp-1tgugnof/src/include/qapi/dealloc-visitor.h:17:0,
from qapi/qapi-types.c:14:
/var/tmp/patchew-tester-tmp-1tgugnof/src/include/qapi/visitor.h:243:5: error: unknown type name ‘QType’
QType type;
^~~~~
In file included from qapi/qapi-types.h:17:0,
from qapi/qapi-types.c:15:
qapi/qapi-types-common.h:95:5: error: unknown type name ‘QType’
QType type;
^~~~~
In file included from qapi/qapi-types-block.h:17:0,
from qapi/qapi-types.h:21,
from qapi/qapi-types.c:15:
qapi/qapi-types-block-core.h:1018:5: error: unknown type name ‘uint64List’
uint64List *boundaries;
^~~~~~~~~~
qapi/qapi-types-block-core.h:1019:5: error: unknown type name ‘uint64List’
uint64List *bins;
^~~~~~~~~~
qapi/qapi-types-block-core.h:1027:5: error: unknown type name ‘uint64List’
uint64List *boundaries;
^~~~~~~~~~
qapi/qapi-types-block-core.h:1029:5: error: unknown type name ‘uint64List’
uint64List *boundaries_read;
^~~~~~~~~~
qapi/qapi-types-block-core.h:1031:5: error: unknown type name ‘uint64List’
uint64List *boundaries_write;
^~~~~~~~~~
qapi/qapi-types-block-core.h:1033:5: error: unknown type name ‘uint64List’
uint64List *boundaries_flush;
^~~~~~~~~~
qapi/qapi-types-block-core.h:1623:5: error: unknown type name ‘QType’
QType type;
^~~~~
qapi/qapi-types-block-core.h:2213:5: error: unknown type name ‘QType’
QType type;
^~~~~
qapi/qapi-types-block-core.h:2225:5: error: unknown type name ‘QType’
QType type;
^~~~~
In file included from qapi/qapi-types.h:23:0,
from qapi/qapi-types.c:15:
qapi/qapi-types-net.h:416:5: error: unknown type name ‘intList’
intList *vlan_table;
^~~~~~~
qapi/qapi-types-net.h:417:5: error: unknown type name ‘strList’
strList *unicast_table;
^~~~~~~
qapi/qapi-types-net.h:418:5: error: unknown type name ‘strList’
strList *multicast_table;
^~~~~~~
In file included from qapi/qapi-types.h:24:0,
from qapi/qapi-types.c:15:
qapi/qapi-types-rocker.h:204:5: error: unknown type name ‘uint32List’
uint32List *group_ids;
^~~~~~~~~~
In file included from qapi/qapi-types.h:30:0,
from qapi/qapi-types.c:15:
qapi/qapi-types-introspect.h:100:5: error: unknown type name ‘strList’
strList *values;
^~~~~~~
In file included from qapi/qapi-types.h:31:0,
from qapi/qapi-types.c:15:
qapi/qapi-types-misc.h:993:5: error: unknown type name ‘strList’
strList *unavailable_features;
^~~~~~~
qapi/qapi-types-misc.h:1023:5: error: unknown type name ‘strList’
strList *responsible_properties;
^~~~~~~
qapi/qapi-types-misc.h:1180:5: error: unknown type name ‘uint16List’
uint16List *cpus;
^~~~~~~~~~
qapi/qapi-types-misc.h:1235:5: error: unknown type name ‘uint16List’
uint16List *host_nodes;
^~~~~~~~~~
make: *** [/var/tmp/patchew-tester-tmp-1tgugnof/src/rules.mak:66: qapi/qapi-types.o] Error 1
In file included from /var/tmp/patchew-tester-tmp-1tgugnof/src/include/qapi/dealloc-visitor.h:17:0,
from qapi/qapi-types-block-core.c:14:
/var/tmp/patchew-tester-tmp-1tgugnof/src/include/qapi/visitor.h:243:5: error: unknown type name ‘QType’
QType type;
^~~~~
In file included from qapi/qapi-types-block-core.h:17:0,
from qapi/qapi-types-block-core.c:15:
qapi/qapi-types-common.h:95:5: error: unknown type name ‘QType’
QType type;
^~~~~
In file included from qapi/qapi-types-block-core.c:15:0:
qapi/qapi-types-block-core.h:1018:5: error: unknown type name ‘uint64List’
uint64List *boundaries;
^~~~~~~~~~
qapi/qapi-types-block-core.h:1019:5: error: unknown type name ‘uint64List’
uint64List *bins;
^~~~~~~~~~
qapi/qapi-types-block-core.h:1027:5: error: unknown type name ‘uint64List’
uint64List *boundaries;
^~~~~~~~~~
qapi/qapi-types-block-core.h:1029:5: error: unknown type name ‘uint64List’
uint64List *boundaries_read;
^~~~~~~~~~
qapi/qapi-types-block-core.h:1031:5: error: unknown type name ‘uint64List’
uint64List *boundaries_write;
^~~~~~~~~~
qapi/qapi-types-block-core.h:1033:5: error: unknown type name ‘uint64List’
uint64List *boundaries_flush;
^~~~~~~~~~
qapi/qapi-types-block-core.h:1623:5: error: unknown type name ‘QType’
QType type;
^~~~~
qapi/qapi-types-block-core.h:2213:5: error: unknown type name ‘QType’
QType type;
^~~~~
qapi/qapi-types-block-core.h:2225:5: error: unknown type name ‘QType’
QType type;
^~~~~
make: *** [/var/tmp/patchew-tester-tmp-1tgugnof/src/rules.mak:66: qapi/qapi-types-block-core.o] Error 1
In file included from /var/tmp/patchew-tester-tmp-1tgugnof/src/include/qapi/dealloc-visitor.h:17:0,
from qapi/qapi-types-block.c:14:
/var/tmp/patchew-tester-tmp-1tgugnof/src/include/qapi/visitor.h:243:5: error: unknown type name ‘QType’
QType type;
^~~~~
In file included from qapi/qapi-types-block-core.h:17:0,
from qapi/qapi-types-block.h:17,
from qapi/qapi-types-block.c:15:
qapi/qapi-types-common.h:95:5: error: unknown type name ‘QType’
QType type;
^~~~~
In file included from qapi/qapi-types-block.h:17:0,
from qapi/qapi-types-block.c:15:
qapi/qapi-types-block-core.h:1018:5: error: unknown type name ‘uint64List’
uint64List *boundaries;
^~~~~~~~~~
qapi/qapi-types-block-core.h:1019:5: error: unknown type name ‘uint64List’
uint64List *bins;
^~~~~~~~~~
qapi/qapi-types-block-core.h:1027:5: error: unknown type name ‘uint64List’
uint64List *boundaries;
^~~~~~~~~~
qapi/qapi-types-block-core.h:1029:5: error: unknown type name ‘uint64List’
uint64List *boundaries_read;
^~~~~~~~~~
qapi/qapi-types-block-core.h:1031:5: error: unknown type name ‘uint64List’
uint64List *boundaries_write;
^~~~~~~~~~
qapi/qapi-types-block-core.h:1033:5: error: unknown type name ‘uint64List’
uint64List *boundaries_flush;
^~~~~~~~~~
qapi/qapi-types-block-core.h:1623:5: error: unknown type name ‘QType’
QType type;
^~~~~
qapi/qapi-types-block-core.h:2213:5: error: unknown type name ‘QType’
QType type;
^~~~~
qapi/qapi-types-block-core.h:2225:5: error: unknown type name ‘QType’
QType type;
^~~~~
make: *** [/var/tmp/patchew-tester-tmp-1tgugnof/src/rules.mak:66: qapi/qapi-types-block.o] Error 1
=== 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] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (49 preceding siblings ...)
2018-03-21 12:47 ` [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code no-reply
@ 2018-03-21 14:20 ` no-reply
2018-03-21 22:08 ` no-reply
` (2 subsequent siblings)
53 siblings, 0 replies; 95+ messages in thread
From: no-reply @ 2018-03-21 14:20 UTC (permalink / raw)
To: marcandre.lureau; +Cc: famz, qemu-devel, armbru
Hi,
This series seems to have some coding style problems. See output below for
more information:
Type: series
Message-id: 20180321115211.17937-1-marcandre.lureau@redhat.com
Subject: [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code
=== TEST SCRIPT BEGIN ===
#!/bin/bash
BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))
done
exit $failed
=== TEST SCRIPT END ===
Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
ca50a2d8e3 RFC: make RTC_CHANGE per-target
032f3d2f59 qapi: remove qmp_unregister_command()
7a4b17cf54 qapi: make query-cpu-definitions depend on specific targets
557f536176 qapi: make query-cpu-model-expansion depend on s390 or x86
dc1b218319 qapi: make query-gic-capabilities depend on TARGET_ARM
af9625c6c3 target.json: add a note about query-cpu* not being s390x-specific
c9801977e9 qapi: make s390 commands depend on TARGET_S390X
6a49803445 qapi: make rtc-reset-reinjection and SEV depend on TARGET_I386
13b093aaae qapi: add a top-unit 'target' schema
8e42b4bfd8 RFC: qapi: learn to split schema by 'top-unit'
2984459cd6 qapi-commands: don't initialize command list in qmp_init_marshall()
7c39c807b5 build-sys: move qmp-introspect per target
af7d5d518d qapi: add conditions to REPLICATION type/commands on the schema
9e583d1a1d qapi: add conditions to SPICE type/commands/events on the schema
8bc16dec62 qapi: add conditions to VNC type/commands/events on the schema
72664dbe15 qapi2texi: add condition to variants
d7ff0ab4ef qapi2texi: add 'If:' condition to struct members
bde44a6b1d qapi2texi: add 'If:' condition to enum values
c87e1bc65f qapi2texi: add 'If:' section to generated documentation
3364d5099f docs: document schema configuration
77f7bafdc4 qapi: add #if conditions to generated code members
a95929de93 qapi: add 'if' to alternate members
b205d6198c qapi: add 'if' on union members
9613ba2cc2 qapi: add an error in case a discriminator is conditionnal
cd025039c0 qapi: add 'if' to implicit struct members
6799c824a8 qapi: add a dictionary form with 'type' key for members
c5b50ed9e3 qapi: rename allow_dict to allow_implicit
ba4011e602 qapi-event: add 'if' condition to implicit event enum
7d828e85b9 qapi: add 'if' to enum members
a20c2dc973 qapi: add a dictionnary form with 'name' key for enum members
061635eff1 qapi: factor out check_known_keys()
b0ad9a471a tests: modify visit_enum_type() in test-qapi to print members
86933fb39c qapi: change enum visitor to take QAPISchemaMember
cd6fb8e83f qapi: rename QAPISchemaEnumType.values to .members
31ea46dcec qapi: do not define enumeration value explicitely
55c7453f3c qapi-types: add #if conditions to types & visitors
4507e44d86 qapi-types: refactor variants handling
9c91a8fa1d qapi/events: add #if conditions to events
7ba12f474f qapi/commands: add #if conditions to commands
fcf4dfeb56 qapi-introspect: add preprocessor conditions to generated QLit
51163f6ba0 qapi-introspect: modify to_qlit() to append ', ' on level > 0
75baac460c qapi: add #if/#endif helpers
a001949a31 qapi: mcgen() shouldn't indent # lines
a2ef5afa63 qapi: add 'ifcond' to visitor methods
688755b5fd qapi: leave the ifcond attribute undefined until check()
0566f4cb49 qapi: pass 'if' condition into QAPISchemaEntity objects
7b98d1b34c qapi: add 'if' to top-level expressions
6c36d8fa28 qapi/events: generate event enum in main module
7ced623f53 qapi/visit: remove useless prefix argument
=== OUTPUT BEGIN ===
Checking PATCH 1/49: qapi/visit: remove useless prefix argument...
Checking PATCH 2/49: qapi/events: generate event enum in main module...
Checking PATCH 3/49: qapi: add 'if' to top-level expressions...
Checking PATCH 4/49: qapi: pass 'if' condition into QAPISchemaEntity objects...
Checking PATCH 5/49: qapi: leave the ifcond attribute undefined until check()...
Checking PATCH 6/49: qapi: add 'ifcond' to visitor methods...
Checking PATCH 7/49: qapi: mcgen() shouldn't indent # lines...
Checking PATCH 8/49: qapi: add #if/#endif helpers...
Checking PATCH 9/49: qapi-introspect: modify to_qlit() to append ', ' on level > 0...
Checking PATCH 10/49: qapi-introspect: add preprocessor conditions to generated QLit...
Checking PATCH 11/49: qapi/commands: add #if conditions to commands...
WARNING: line over 80 characters
#53: FILE: scripts/qapi/commands.py:289:
+ self._regy.add(gen_register_command(name, success_response, allow_oob))
total: 0 errors, 1 warnings, 49 lines checked
Your patch has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 12/49: qapi/events: add #if conditions to events...
WARNING: line over 80 characters
#27: FILE: scripts/qapi/events.py:190:
+ self._genc.add(gen_event_send(name, arg_type, boxed, self._enum_name))
total: 0 errors, 1 warnings, 11 lines checked
Your patch has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 13/49: qapi-types: refactor variants handling...
Checking PATCH 14/49: qapi-types: add #if conditions to types & visitors...
Checking PATCH 15/49: qapi: do not define enumeration value explicitely...
Checking PATCH 16/49: qapi: rename QAPISchemaEnumType.values to .members...
Checking PATCH 17/49: qapi: change enum visitor to take QAPISchemaMember...
Checking PATCH 18/49: tests: modify visit_enum_type() in test-qapi to print members...
Checking PATCH 19/49: qapi: factor out check_known_keys()...
Checking PATCH 20/49: qapi: add a dictionnary form with 'name' key for enum members...
Checking PATCH 21/49: qapi: add 'if' to enum members...
Checking PATCH 22/49: qapi-event: add 'if' condition to implicit event enum...
Checking PATCH 23/49: qapi: rename allow_dict to allow_implicit...
Checking PATCH 24/49: qapi: add a dictionary form with 'type' key for members...
Checking PATCH 25/49: qapi: add 'if' to implicit struct members...
Checking PATCH 26/49: qapi: add an error in case a discriminator is conditionnal...
Checking PATCH 27/49: qapi: add 'if' on union members...
Checking PATCH 28/49: qapi: add 'if' to alternate members...
Checking PATCH 29/49: qapi: add #if conditions to generated code members...
Checking PATCH 30/49: docs: document schema configuration...
Checking PATCH 31/49: qapi2texi: add 'If:' section to generated documentation...
Checking PATCH 32/49: qapi2texi: add 'If:' condition to enum values...
Checking PATCH 33/49: qapi2texi: add 'If:' condition to struct members...
Checking PATCH 34/49: qapi2texi: add condition to variants...
Checking PATCH 35/49: qapi: add conditions to VNC type/commands/events on the schema...
Checking PATCH 36/49: qapi: add conditions to SPICE type/commands/events on the schema...
Checking PATCH 37/49: qapi: add conditions to REPLICATION type/commands on the schema...
Checking PATCH 38/49: build-sys: move qmp-introspect per target...
Checking PATCH 39/49: qapi-commands: don't initialize command list in qmp_init_marshall()...
Checking PATCH 40/49: RFC: qapi: learn to split schema by 'top-unit'...
WARNING: line over 80 characters
#102: FILE: scripts/qapi/common.py:304:
+ incl_info['has-pragma-top-unit'] = exprs_include._top_unit
WARNING: line over 80 characters
#340: FILE: scripts/qapi/events.py:165:
+ self._enum_name = c_name(self._prefix_unit() + 'QAPIEvent', protect=False)
total: 0 errors, 2 warnings, 350 lines checked
Your patch has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 41/49: qapi: add a top-unit 'target' schema...
Checking PATCH 42/49: qapi: make rtc-reset-reinjection and SEV depend on TARGET_I386...
Checking PATCH 43/49: qapi: make s390 commands depend on TARGET_S390X...
Checking PATCH 44/49: target.json: add a note about query-cpu* not being s390x-specific...
Checking PATCH 45/49: qapi: make query-gic-capabilities depend on TARGET_ARM...
Checking PATCH 46/49: qapi: make query-cpu-model-expansion depend on s390 or x86...
Checking PATCH 47/49: qapi: make query-cpu-definitions depend on specific targets...
Checking PATCH 48/49: qapi: remove qmp_unregister_command()...
Checking PATCH 49/49: RFC: make RTC_CHANGE per-target...
ERROR: line over 90 characters
#65: FILE: monitor.c:682:
+#if defined(TARGET_ALPHA) || defined(TARGET_ARM) || defined(TARGET_HPPA) || defined(TARGET_I386) || defined(TARGET_MIPS) | defined(TARGET_MIPS64) || defined(TARGET_MOXIE) || defined(TARGET_PPC) || defined(TARGET_PPC64) || defined(TARGET_S390X) || defined(TARGET_SH4) || defined(TARGET_SPARC)
total: 1 errors, 0 warnings, 89 lines checked
Your patch has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
=== OUTPUT END ===
Test command exited with code: 1
---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (50 preceding siblings ...)
2018-03-21 14:20 ` no-reply
@ 2018-03-21 22:08 ` no-reply
2018-03-22 5:11 ` no-reply
2018-06-21 16:47 ` Markus Armbruster
53 siblings, 0 replies; 95+ messages in thread
From: no-reply @ 2018-03-21 22:08 UTC (permalink / raw)
To: marcandre.lureau; +Cc: famz, qemu-devel, armbru
Hi,
This series failed docker-quick@centos6 build test. Please find the testing commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.
Type: series
Message-id: 20180321115211.17937-1-marcandre.lureau@redhat.com
Subject: [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code
=== 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
=== TEST SCRIPT END ===
Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
* [new tag] patchew/1521665220-3869-1-git-send-email-mjc@sifive.com -> patchew/1521665220-3869-1-git-send-email-mjc@sifive.com
* [new tag] patchew/20180321211056.3339-1-yuval.shaia@oracle.com -> patchew/20180321211056.3339-1-yuval.shaia@oracle.com
Switched to a new branch 'test'
ca50a2d8e3 RFC: make RTC_CHANGE per-target
032f3d2f59 qapi: remove qmp_unregister_command()
7a4b17cf54 qapi: make query-cpu-definitions depend on specific targets
557f536176 qapi: make query-cpu-model-expansion depend on s390 or x86
dc1b218319 qapi: make query-gic-capabilities depend on TARGET_ARM
af9625c6c3 target.json: add a note about query-cpu* not being s390x-specific
c9801977e9 qapi: make s390 commands depend on TARGET_S390X
6a49803445 qapi: make rtc-reset-reinjection and SEV depend on TARGET_I386
13b093aaae qapi: add a top-unit 'target' schema
8e42b4bfd8 RFC: qapi: learn to split schema by 'top-unit'
2984459cd6 qapi-commands: don't initialize command list in qmp_init_marshall()
7c39c807b5 build-sys: move qmp-introspect per target
af7d5d518d qapi: add conditions to REPLICATION type/commands on the schema
9e583d1a1d qapi: add conditions to SPICE type/commands/events on the schema
8bc16dec62 qapi: add conditions to VNC type/commands/events on the schema
72664dbe15 qapi2texi: add condition to variants
d7ff0ab4ef qapi2texi: add 'If:' condition to struct members
bde44a6b1d qapi2texi: add 'If:' condition to enum values
c87e1bc65f qapi2texi: add 'If:' section to generated documentation
3364d5099f docs: document schema configuration
77f7bafdc4 qapi: add #if conditions to generated code members
a95929de93 qapi: add 'if' to alternate members
b205d6198c qapi: add 'if' on union members
9613ba2cc2 qapi: add an error in case a discriminator is conditionnal
cd025039c0 qapi: add 'if' to implicit struct members
6799c824a8 qapi: add a dictionary form with 'type' key for members
c5b50ed9e3 qapi: rename allow_dict to allow_implicit
ba4011e602 qapi-event: add 'if' condition to implicit event enum
7d828e85b9 qapi: add 'if' to enum members
a20c2dc973 qapi: add a dictionnary form with 'name' key for enum members
061635eff1 qapi: factor out check_known_keys()
b0ad9a471a tests: modify visit_enum_type() in test-qapi to print members
86933fb39c qapi: change enum visitor to take QAPISchemaMember
cd6fb8e83f qapi: rename QAPISchemaEnumType.values to .members
31ea46dcec qapi: do not define enumeration value explicitely
55c7453f3c qapi-types: add #if conditions to types & visitors
4507e44d86 qapi-types: refactor variants handling
9c91a8fa1d qapi/events: add #if conditions to events
7ba12f474f qapi/commands: add #if conditions to commands
fcf4dfeb56 qapi-introspect: add preprocessor conditions to generated QLit
51163f6ba0 qapi-introspect: modify to_qlit() to append ', ' on level > 0
75baac460c qapi: add #if/#endif helpers
a001949a31 qapi: mcgen() shouldn't indent # lines
a2ef5afa63 qapi: add 'ifcond' to visitor methods
688755b5fd qapi: leave the ifcond attribute undefined until check()
0566f4cb49 qapi: pass 'if' condition into QAPISchemaEntity objects
7b98d1b34c qapi: add 'if' to top-level expressions
6c36d8fa28 qapi/events: generate event enum in main module
7ced623f53 qapi/visit: remove useless prefix argument
=== OUTPUT BEGIN ===
Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path 'dtc'
Cloning into '/var/tmp/patchew-tester-tmp-_42j_rgl/src/dtc'...
Submodule path 'dtc': checked out 'e54388015af1fb4bf04d0bca99caba1074d9cc42'
BUILD centos6
make[1]: Entering directory '/var/tmp/patchew-tester-tmp-_42j_rgl/src'
GEN /var/tmp/patchew-tester-tmp-_42j_rgl/src/docker-src.2018-03-21-18.07.28.25329/qemu.tar
Cloning into '/var/tmp/patchew-tester-tmp-_42j_rgl/src/docker-src.2018-03-21-18.07.28.25329/qemu.tar.vroot'...
done.
Your branch is up-to-date with 'origin/test'.
Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path 'dtc'
Cloning into '/var/tmp/patchew-tester-tmp-_42j_rgl/src/docker-src.2018-03-21-18.07.28.25329/qemu.tar.vroot/dtc'...
Submodule path 'dtc': checked out 'e54388015af1fb4bf04d0bca99caba1074d9cc42'
Submodule 'ui/keycodemapdb' (git://git.qemu.org/keycodemapdb.git) registered for path 'ui/keycodemapdb'
Cloning into '/var/tmp/patchew-tester-tmp-_42j_rgl/src/docker-src.2018-03-21-18.07.28.25329/qemu.tar.vroot/ui/keycodemapdb'...
Submodule path 'ui/keycodemapdb': checked out '6b3d716e2b6472eb7189d3220552280ef3d832ce'
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
gettext-0.17-18.el6.x86_64
git-1.7.1-9.el6_9.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.6-2.el6.x86_64
zlib-devel-1.2.3-29.el6.x86_64
Environment variables:
PACKAGES=bison bzip2-devel ccache csnappy-devel flex g++ gcc gettext 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=82b26ca1d6f9
MAKEFLAGS= -j8
J=8
CCACHE_DIR=/var/tmp/ccache
EXTRA_CONFIGURE_OPTS=
V=
SHOW_ENV=1
PATH=/usr/lib/ccache:/usr/lib64/ccache:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
TARGET_LIST=
SHLVL=1
HOME=/root
TEST_DIR=/tmp/qemu-test
FEATURES= dtc
DEBUG=
_=/usr/bin/env
Configure options:
--enable-werror --target-list=x86_64-softmmu,aarch64-softmmu --prefix=/tmp/qemu-test/install
No C++ compiler available; disabling C++ specific optional code
Install prefix /tmp/qemu-test/install
BIOS directory /tmp/qemu-test/install/share/qemu
firmware path /tmp/qemu-test/install/share/qemu-firmware
binary directory /tmp/qemu-test/install/bin
library directory /tmp/qemu-test/install/lib
module directory /tmp/qemu-test/install/lib/qemu
libexec directory /tmp/qemu-test/install/libexec
include directory /tmp/qemu-test/install/include
config directory /tmp/qemu-test/install/etc
local state directory /tmp/qemu-test/install/var
Manual directory /tmp/qemu-test/install/share/man
ELF interp prefix /usr/gnemul/qemu-%M
Source path /tmp/qemu-test/src
GIT binary git
GIT submodules
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 -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 -Wno-missing-braces -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
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
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
Multipath 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
HVF support no
WHPX support no
TCG support yes
TCG debug enabled no
TCG interpreter no
malloc trim support yes
RDMA support no
fdt support yes
membarrier no
preadv support yes
fdatasync yes
madvise yes
posix_madvise yes
posix_memalign yes
libcap-ng support no
vhost-net support yes
vhost-crypto 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
TPM emulator yes
QOM debugging yes
Live block migration yes
lzo support yes
snappy support no
bzip2 support yes
NUMA host support no
libxml2 no
tcmalloc support no
jemalloc support no
avx2 optimization no
replication support yes
VxHS block device no
capstone no
WARNING: Use of GTK 2.0 is deprecated and will be removed in
WARNING: future releases. Please switch to using GTK 3.0
WARNING: Use of SDL 1.2 is deprecated and will be removed in
WARNING: future releases. Please switch to using SDL 2.0
GEN x86_64-softmmu/config-devices.mak.tmp
GEN aarch64-softmmu/config-devices.mak.tmp
mkdir -p dtc/libfdt
GEN config-host.h
mkdir -p dtc/tests
GEN qemu-options.def
GEN qapi-gen
GEN trace/generated-tcg-tracers.h
GEN trace/generated-helpers-wrappers.h
GEN trace/generated-helpers.h
GEN x86_64-softmmu/config-devices.mak
GEN aarch64-softmmu/config-devices.mak
GEN trace/generated-helpers.c
GEN module_block.h
Traceback (most recent call last):
File "/tmp/qemu-test/src/scripts/qapi-gen.py", line 11, in <module>
from qapi.common import QAPIError, QAPISchema
File "/tmp/qemu-test/src/scripts/qapi/common.py", line 987
if {'union', 'alternate', 'struct', 'command', 'event'} & set(expr):
^
SyntaxError: invalid syntax
make: *** [qapi-gen-timestamp] Error 1
make: *** Waiting for unfinished jobs....
Traceback (most recent call last):
File "./tests/docker/docker.py", line 407, in <module>
sys.exit(main())
File "./tests/docker/docker.py", line 404, in main
return args.cmdobj.run(args, argv)
File "./tests/docker/docker.py", line 261, in run
return Docker().run(argv, args.keep, quiet=args.quiet)
File "./tests/docker/docker.py", line 229, in run
quiet=quiet)
File "./tests/docker/docker.py", line 147, 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=48e2d3042d5411e8a75c52540069c830', '-u', '0', '--security-opt', 'seccomp=unconfined', '--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', '/root/.cache/qemu-docker-ccache:/var/tmp/ccache:z', '-v', '/var/tmp/patchew-tester-tmp-_42j_rgl/src/docker-src.2018-03-21-18.07.28.25329:/var/tmp/qemu:z,ro', 'qemu:centos6', '/var/tmp/qemu/run', 'test-quick']' returned non-zero exit status 2
make[1]: *** [tests/docker/Makefile.include:129: docker-run] Error 1
make[1]: Leaving directory '/var/tmp/patchew-tester-tmp-_42j_rgl/src'
make: *** [tests/docker/Makefile.include:163: docker-run-test-quick@centos6] Error 2
real 1m23.270s
user 0m8.174s
sys 0m6.373s
=== 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] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (51 preceding siblings ...)
2018-03-21 22:08 ` no-reply
@ 2018-03-22 5:11 ` no-reply
2018-06-21 16:47 ` Markus Armbruster
53 siblings, 0 replies; 95+ messages in thread
From: no-reply @ 2018-03-22 5:11 UTC (permalink / raw)
To: marcandre.lureau; +Cc: famz, qemu-devel, armbru
Hi,
This series failed docker-build@min-glib build test. Please find the testing commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.
Type: series
Message-id: 20180321115211.17937-1-marcandre.lureau@redhat.com
Subject: [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code
=== 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-build@min-glib
=== TEST SCRIPT END ===
Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
t [tag update] patchew/20180321211056.3339-1-yuval.shaia@oracle.com -> patchew/20180321211056.3339-1-yuval.shaia@oracle.com
Switched to a new branch 'test'
ca50a2d8e3 RFC: make RTC_CHANGE per-target
032f3d2f59 qapi: remove qmp_unregister_command()
7a4b17cf54 qapi: make query-cpu-definitions depend on specific targets
557f536176 qapi: make query-cpu-model-expansion depend on s390 or x86
dc1b218319 qapi: make query-gic-capabilities depend on TARGET_ARM
af9625c6c3 target.json: add a note about query-cpu* not being s390x-specific
c9801977e9 qapi: make s390 commands depend on TARGET_S390X
6a49803445 qapi: make rtc-reset-reinjection and SEV depend on TARGET_I386
13b093aaae qapi: add a top-unit 'target' schema
8e42b4bfd8 RFC: qapi: learn to split schema by 'top-unit'
2984459cd6 qapi-commands: don't initialize command list in qmp_init_marshall()
7c39c807b5 build-sys: move qmp-introspect per target
af7d5d518d qapi: add conditions to REPLICATION type/commands on the schema
9e583d1a1d qapi: add conditions to SPICE type/commands/events on the schema
8bc16dec62 qapi: add conditions to VNC type/commands/events on the schema
72664dbe15 qapi2texi: add condition to variants
d7ff0ab4ef qapi2texi: add 'If:' condition to struct members
bde44a6b1d qapi2texi: add 'If:' condition to enum values
c87e1bc65f qapi2texi: add 'If:' section to generated documentation
3364d5099f docs: document schema configuration
77f7bafdc4 qapi: add #if conditions to generated code members
a95929de93 qapi: add 'if' to alternate members
b205d6198c qapi: add 'if' on union members
9613ba2cc2 qapi: add an error in case a discriminator is conditionnal
cd025039c0 qapi: add 'if' to implicit struct members
6799c824a8 qapi: add a dictionary form with 'type' key for members
c5b50ed9e3 qapi: rename allow_dict to allow_implicit
ba4011e602 qapi-event: add 'if' condition to implicit event enum
7d828e85b9 qapi: add 'if' to enum members
a20c2dc973 qapi: add a dictionnary form with 'name' key for enum members
061635eff1 qapi: factor out check_known_keys()
b0ad9a471a tests: modify visit_enum_type() in test-qapi to print members
86933fb39c qapi: change enum visitor to take QAPISchemaMember
cd6fb8e83f qapi: rename QAPISchemaEnumType.values to .members
31ea46dcec qapi: do not define enumeration value explicitely
55c7453f3c qapi-types: add #if conditions to types & visitors
4507e44d86 qapi-types: refactor variants handling
9c91a8fa1d qapi/events: add #if conditions to events
7ba12f474f qapi/commands: add #if conditions to commands
fcf4dfeb56 qapi-introspect: add preprocessor conditions to generated QLit
51163f6ba0 qapi-introspect: modify to_qlit() to append ', ' on level > 0
75baac460c qapi: add #if/#endif helpers
a001949a31 qapi: mcgen() shouldn't indent # lines
a2ef5afa63 qapi: add 'ifcond' to visitor methods
688755b5fd qapi: leave the ifcond attribute undefined until check()
0566f4cb49 qapi: pass 'if' condition into QAPISchemaEntity objects
7b98d1b34c qapi: add 'if' to top-level expressions
6c36d8fa28 qapi/events: generate event enum in main module
7ced623f53 qapi/visit: remove useless prefix argument
=== OUTPUT BEGIN ===
Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path 'dtc'
Cloning into '/var/tmp/patchew-tester-tmp-6a3ah8qp/src/dtc'...
Submodule path 'dtc': checked out 'e54388015af1fb4bf04d0bca99caba1074d9cc42'
BUILD min-glib
make[1]: Entering directory '/var/tmp/patchew-tester-tmp-6a3ah8qp/src'
GEN /var/tmp/patchew-tester-tmp-6a3ah8qp/src/docker-src.2018-03-22-01.10.50.7274/qemu.tar
Cloning into '/var/tmp/patchew-tester-tmp-6a3ah8qp/src/docker-src.2018-03-22-01.10.50.7274/qemu.tar.vroot'...
done.
Your branch is up-to-date with 'origin/test'.
Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path 'dtc'
Cloning into '/var/tmp/patchew-tester-tmp-6a3ah8qp/src/docker-src.2018-03-22-01.10.50.7274/qemu.tar.vroot/dtc'...
Submodule path 'dtc': checked out 'e54388015af1fb4bf04d0bca99caba1074d9cc42'
Submodule 'ui/keycodemapdb' (git://git.qemu.org/keycodemapdb.git) registered for path 'ui/keycodemapdb'
Cloning into '/var/tmp/patchew-tester-tmp-6a3ah8qp/src/docker-src.2018-03-22-01.10.50.7274/qemu.tar.vroot/ui/keycodemapdb'...
Submodule path 'ui/keycodemapdb': checked out '6b3d716e2b6472eb7189d3220552280ef3d832ce'
COPY RUNNER
RUN test-build in qemu:min-glib
Environment variables:
HOSTNAME=17719477dad1
MAKEFLAGS= -j8
J=8
CCACHE_DIR=/var/tmp/ccache
EXTRA_CONFIGURE_OPTS=
V=
SHOW_ENV=1
PATH=/usr/lib/ccache:/usr/lib64/ccache:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
TARGET_LIST=
SHLVL=1
HOME=/root
TEST_DIR=/tmp/qemu-test
FEATURES= dtc
DEBUG=
_=/usr/bin/env
Configure options:
--enable-werror --target-list=x86_64-softmmu,aarch64-softmmu --prefix=/tmp/qemu-test/install
No C++ compiler available; disabling C++ specific optional code
Install prefix /tmp/qemu-test/install
BIOS directory /tmp/qemu-test/install/share/qemu
firmware path /tmp/qemu-test/install/share/qemu-firmware
binary directory /tmp/qemu-test/install/bin
library directory /tmp/qemu-test/install/lib
module directory /tmp/qemu-test/install/lib/qemu
libexec directory /tmp/qemu-test/install/libexec
include directory /tmp/qemu-test/install/include
config directory /tmp/qemu-test/install/etc
local state directory /tmp/qemu-test/install/var
Manual directory /tmp/qemu-test/install/share/man
ELF interp prefix /usr/gnemul/qemu-%M
Source path /tmp/qemu-test/src
GIT binary git
GIT submodules
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 -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 -Wno-missing-braces
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
SDL support yes (1.2.14)
GTK support no
GTK GL support no
VTE support no
TLS priority NORMAL
GNUTLS support no
GNUTLS rnd no
libgcrypt no
libgcrypt kdf no
nettle no
nettle kdf no
libtasn1 no
curses support no
virgl support no
curl support no
mingw32 support no
Audio drivers oss
Block whitelist (rw)
Block whitelist (ro)
VirtFS support no
Multipath support no
VNC support yes
VNC SASL support no
VNC JPEG support no
VNC PNG support no
xen support 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
HVF support no
WHPX support no
TCG support yes
TCG debug enabled no
TCG interpreter no
malloc trim support yes
RDMA support no
fdt support yes
membarrier no
preadv support yes
fdatasync yes
madvise yes
posix_madvise yes
posix_memalign yes
libcap-ng support no
vhost-net support yes
vhost-crypto support yes
vhost-scsi support yes
vhost-vsock support yes
vhost-user support yes
Trace backends log
spice support no
rbd support no
xfsctl support no
smartcard support no
libusb no
usb net redir no
OpenGL support no
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
TPM emulator yes
QOM debugging yes
Live block migration yes
lzo support no
snappy support no
bzip2 support no
NUMA host support no
libxml2 no
tcmalloc support no
jemalloc support no
avx2 optimization no
replication support yes
VxHS block device no
capstone no
WARNING: Use of SDL 1.2 is deprecated and will be removed in
WARNING: future releases. Please switch to using SDL 2.0
mkdir -p dtc/libfdt
mkdir -p dtc/tests
GEN x86_64-softmmu/config-devices.mak.tmp
GEN aarch64-softmmu/config-devices.mak.tmp
GEN config-host.h
GEN qemu-options.def
GEN qapi-gen
GEN trace/generated-tcg-tracers.h
GEN trace/generated-helpers-wrappers.h
GEN trace/generated-helpers.h
GEN aarch64-softmmu/config-devices.mak
GEN x86_64-softmmu/config-devices.mak
GEN trace/generated-helpers.c
GEN module_block.h
GEN ui/input-keymap-atset1-to-qcode.c
GEN ui/input-keymap-linux-to-qcode.c
GEN ui/input-keymap-qcode-to-atset1.c
GEN ui/input-keymap-qcode-to-atset2.c
GEN ui/input-keymap-qcode-to-atset3.c
GEN ui/input-keymap-qcode-to-linux.c
Traceback (most recent call last):
File "/tmp/qemu-test/src/scripts/qapi-gen.py", line 11, in <module>
from qapi.common import QAPIError, QAPISchema
File "/tmp/qemu-test/src/scripts/qapi/common.py", line 987
if {'union', 'alternate', 'struct', 'command', 'event'} & set(expr):
^
SyntaxError: invalid syntax
make: *** [qapi-gen-timestamp] Error 1
make: *** Waiting for unfinished jobs....
Traceback (most recent call last):
File "./tests/docker/docker.py", line 407, in <module>
sys.exit(main())
File "./tests/docker/docker.py", line 404, in main
return args.cmdobj.run(args, argv)
File "./tests/docker/docker.py", line 261, in run
return Docker().run(argv, args.keep, quiet=args.quiet)
File "./tests/docker/docker.py", line 229, in run
quiet=quiet)
File "./tests/docker/docker.py", line 147, 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=6d6d77202d8f11e8b66352540069c830', '-u', '0', '--security-opt', 'seccomp=unconfined', '--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', '/root/.cache/qemu-docker-ccache:/var/tmp/ccache:z', '-v', '/var/tmp/patchew-tester-tmp-6a3ah8qp/src/docker-src.2018-03-22-01.10.50.7274:/var/tmp/qemu:z,ro', 'qemu:min-glib', '/var/tmp/qemu/run', 'test-build']' returned non-zero exit status 2
make[1]: *** [tests/docker/Makefile.include:129: docker-run] Error 1
make[1]: Leaving directory '/var/tmp/patchew-tester-tmp-6a3ah8qp/src'
make: *** [tests/docker/Makefile.include:163: docker-run-test-build@min-glib] Error 2
real 1m9.340s
user 0m8.633s
sys 0m6.243s
=== 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] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 43/49] qapi: make s390 commands depend on TARGET_S390X
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 43/49] qapi: make s390 commands depend on TARGET_S390X Marc-André Lureau
@ 2018-03-22 5:42 ` Thomas Huth
2018-03-22 9:41 ` Marc-André Lureau
0 siblings, 1 reply; 95+ messages in thread
From: Thomas Huth @ 2018-03-22 5:42 UTC (permalink / raw)
To: Marc-André Lureau, qemu-devel, David Hildenbrand
Cc: armbru, Qemu-s390x list
On 21.03.2018 12:52, Marc-André Lureau wrote:
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> Acked-by: Cornelia Huck <cohuck@redhat.com>
> ---
> qapi/misc.json | 101 ----------------------
> qapi/target.json | 106 ++++++++++++++++++++++++
> 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 | 13 ---
> stubs/arch-query-cpu-model-comparison.c | 13 ---
> target/s390x/cpu_models.c | 5 +-
> stubs/Makefile.objs | 2 -
> 10 files changed, 110 insertions(+), 167 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/misc.json b/qapi/misc.json
> index 690eeda41f..1753a81b1e 100644
> --- a/qapi/misc.json
> +++ b/qapi/misc.json
> @@ -1821,27 +1821,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:
> #
> @@ -2208,46 +2187,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:
> #
> @@ -2260,46 +2199,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 f277b69a2a..b07a8926d8 100644
> --- a/qapi/target.json
> +++ b/qapi/target.json
> @@ -7,6 +7,8 @@
>
> { 'pragma': { 'top-unit': 'target' } }
>
> +{ 'include': 'misc.json' }
> +
> ##
> # @rtc-reset-reinjection:
> #
> @@ -182,3 +184,107 @@
> ##
> { 'command': 'query-sev-capabilities', 'returns': 'SevCapability',
> '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 32abdfe6a1..f0ef652b2a 100644
> --- a/include/sysemu/arch_init.h
> +++ b/include/sysemu/arch_init.h
> @@ -36,11 +36,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 76241c240e..59d28c2358 100644
> --- a/hw/s390x/s390-skeys.c
> +++ b/hw/s390x/s390-skeys.c
> @@ -13,7 +13,7 @@
> #include "hw/boards.h"
> #include "hw/s390x/storage-keys.h"
> #include "qapi/error.h"
> -#include "qapi/qapi-commands-misc.h"
> +#include "qapi/target-qapi-commands.h"
> #include "qapi/qmp/qdict.h"
> #include "qemu/error-report.h"
> #include "sysemu/kvm.h"
> diff --git a/monitor.c b/monitor.c
> index 4ad9225425..bd9a6950cf 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -1157,19 +1157,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");
> @@ -4703,13 +4696,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 d8f80cb04e..14972b78df 100644
> --- a/qmp.c
> +++ b/qmp.c
> @@ -601,20 +601,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);
> -}
Not sure, but couldn't these two commands be implemented on other
architectures in the long run, too? So removing them now here seems
somewhat counterproductive?
Thomas
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 43/49] qapi: make s390 commands depend on TARGET_S390X
2018-03-22 5:42 ` Thomas Huth
@ 2018-03-22 9:41 ` Marc-André Lureau
2018-03-22 16:10 ` Thomas Huth
0 siblings, 1 reply; 95+ messages in thread
From: Marc-André Lureau @ 2018-03-22 9:41 UTC (permalink / raw)
To: Thomas Huth; +Cc: QEMU, David Hildenbrand, Qemu-s390x list, Markus Armbruster
Hi
On Thu, Mar 22, 2018 at 6:42 AM, Thomas Huth <thuth@redhat.com> wrote:
> On 21.03.2018 12:52, Marc-André Lureau wrote:
>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>> Acked-by: Cornelia Huck <cohuck@redhat.com>
>> ---
>> qapi/misc.json | 101 ----------------------
>> qapi/target.json | 106 ++++++++++++++++++++++++
>> 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 | 13 ---
>> stubs/arch-query-cpu-model-comparison.c | 13 ---
>> target/s390x/cpu_models.c | 5 +-
>> stubs/Makefile.objs | 2 -
>> 10 files changed, 110 insertions(+), 167 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/misc.json b/qapi/misc.json
>> index 690eeda41f..1753a81b1e 100644
>> --- a/qapi/misc.json
>> +++ b/qapi/misc.json
>> @@ -1821,27 +1821,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:
>> #
>> @@ -2208,46 +2187,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:
>> #
>> @@ -2260,46 +2199,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 f277b69a2a..b07a8926d8 100644
>> --- a/qapi/target.json
>> +++ b/qapi/target.json
>> @@ -7,6 +7,8 @@
>>
>> { 'pragma': { 'top-unit': 'target' } }
>>
>> +{ 'include': 'misc.json' }
>> +
>> ##
>> # @rtc-reset-reinjection:
>> #
>> @@ -182,3 +184,107 @@
>> ##
>> { 'command': 'query-sev-capabilities', 'returns': 'SevCapability',
>> '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 32abdfe6a1..f0ef652b2a 100644
>> --- a/include/sysemu/arch_init.h
>> +++ b/include/sysemu/arch_init.h
>> @@ -36,11 +36,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 76241c240e..59d28c2358 100644
>> --- a/hw/s390x/s390-skeys.c
>> +++ b/hw/s390x/s390-skeys.c
>> @@ -13,7 +13,7 @@
>> #include "hw/boards.h"
>> #include "hw/s390x/storage-keys.h"
>> #include "qapi/error.h"
>> -#include "qapi/qapi-commands-misc.h"
>> +#include "qapi/target-qapi-commands.h"
>> #include "qapi/qmp/qdict.h"
>> #include "qemu/error-report.h"
>> #include "sysemu/kvm.h"
>> diff --git a/monitor.c b/monitor.c
>> index 4ad9225425..bd9a6950cf 100644
>> --- a/monitor.c
>> +++ b/monitor.c
>> @@ -1157,19 +1157,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");
>> @@ -4703,13 +4696,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 d8f80cb04e..14972b78df 100644
>> --- a/qmp.c
>> +++ b/qmp.c
>> @@ -601,20 +601,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);
>> -}
>
> Not sure, but couldn't these two commands be implemented on other
> architectures in the long run, too? So removing them now here seems
> somewhat counterproductive?
They would have modify the qapi ifdef and implement the qmp handler in
their target, similar to what would be done by implementing arch_query
handlers. How counterproductive is that? The benefit is that we don't
have to have stubs and "de-register" the commands.
--
Marc-André Lureau
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 43/49] qapi: make s390 commands depend on TARGET_S390X
2018-03-22 9:41 ` Marc-André Lureau
@ 2018-03-22 16:10 ` Thomas Huth
0 siblings, 0 replies; 95+ messages in thread
From: Thomas Huth @ 2018-03-22 16:10 UTC (permalink / raw)
To: Marc-André Lureau
Cc: QEMU, David Hildenbrand, Qemu-s390x list, Markus Armbruster
On 22.03.2018 10:41, Marc-André Lureau wrote:
> Hi
>
> On Thu, Mar 22, 2018 at 6:42 AM, Thomas Huth <thuth@redhat.com> wrote:
>> On 21.03.2018 12:52, Marc-André Lureau wrote:
[...]
>>> diff --git a/qmp.c b/qmp.c
>>> index d8f80cb04e..14972b78df 100644
>>> --- a/qmp.c
>>> +++ b/qmp.c
>>> @@ -601,20 +601,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);
>>> -}
>>
>> Not sure, but couldn't these two commands be implemented on other
>> architectures in the long run, too? So removing them now here seems
>> somewhat counterproductive?
>
> They would have modify the qapi ifdef and implement the qmp handler in
> their target, similar to what would be done by implementing arch_query
> handlers. How counterproductive is that? The benefit is that we don't
> have to have stubs and "de-register" the commands.
Yes, thinking about that again, I guess you're right, this should be
fine. I first thought that there would likely be some common code
between the targets finally, but it's more likely that this CPU stuff is
completely different everywhere. So never mind!
Thomas
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 01/49] qapi/visit: remove useless prefix argument
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 01/49] qapi/visit: remove useless prefix argument Marc-André Lureau
@ 2018-06-18 14:29 ` Markus Armbruster
0 siblings, 0 replies; 95+ messages in thread
From: Markus Armbruster @ 2018-06-18 14:29 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, armbru
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi/visit.py | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py
> index 5d72d8936c..3c5ea1289e 100644
> --- a/scripts/qapi/visit.py
> +++ b/scripts/qapi/visit.py
> @@ -293,7 +293,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor):
> #include "qapi/qmp/qerror.h"
> #include "%(visit)s.h"
> ''',
> - visit=visit, prefix=self._prefix))
> + visit=visit))
> self._genh.preamble_add(mcgen('''
> #include "qapi/qapi-builtin-visit.h"
> #include "%(types)s.h"
Reviewed-by: Markus Armbruster <armbru@redhat.com>
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 02/49] qapi/events: generate event enum in main module
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 02/49] qapi/events: generate event enum in main module Marc-André Lureau
@ 2018-06-18 14:33 ` Markus Armbruster
0 siblings, 0 replies; 95+ messages in thread
From: Markus Armbruster @ 2018-06-18 14:33 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> The event generator produces an enum, and put it in the last visited
> module. It fits better in the main module, since it's the set of all
> visited events, from all modules.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi/events.py | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/scripts/qapi/events.py b/scripts/qapi/events.py
> index 3dc523cf39..3e448ae523 100644
> --- a/scripts/qapi/events.py
> +++ b/scripts/qapi/events.py
> @@ -180,8 +180,9 @@ class QAPISchemaGenEventVisitor(QAPISchemaModularCVisitor):
> types=types))
>
> def visit_end(self):
> - self._genh.add(gen_enum(self._enum_name, self._event_names))
> - self._genc.add(gen_enum_lookup(self._enum_name, self._event_names))
> + (genc, genh) = self._module[self._main_module]
> + genh.add(gen_enum(self._enum_name, self._event_names))
> + genc.add(gen_enum_lookup(self._enum_name, self._event_names))
>
> def visit_event(self, name, info, arg_type, boxed):
> self._genh.add(gen_event_send_decl(name, arg_type, boxed))
Much better indeed.
Reviewed-by: Markus Armbruster <armbru@redhat.com>
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 03/49] qapi: add 'if' to top-level expressions
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 03/49] qapi: add 'if' to top-level expressions Marc-André Lureau
@ 2018-06-19 7:57 ` Markus Armbruster
2018-06-19 8:41 ` Marc-André Lureau
0 siblings, 1 reply; 95+ messages in thread
From: Markus Armbruster @ 2018-06-19 7:57 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel
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>
[...]
> diff --git a/tests/Makefile.include b/tests/Makefile.include
> index 0b277036df..f77ad2ba3b 100644
> --- a/tests/Makefile.include
> +++ b/tests/Makefile.include
> @@ -436,6 +436,10 @@ 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-if-list.json
> qapi-schema += bad-type-bool.json
> qapi-schema += bad-type-dict.json
> qapi-schema += bad-type-int.json
> @@ -933,6 +937,8 @@ $(patsubst %, check-%, $(check-qapi-schema-y)): check-%.json: $(SRC_PATH)/%.json
> "TEST","$*.out")
> @# Sanitize error messages (make them independent of build directory)
> @perl -p -e 's|\Q$(SRC_PATH)\E/||g' $*.test.err | diff -u $(SRC_PATH)/$*.err -
> + @if test "$(QAPI_REGENERATE)" == 1 ; then cp $*.test.out $(SRC_PATH)/$*.out ; fi
> + @if test "$(QAPI_REGENERATE)" == 1 ; then cp $*.test.err $(SRC_PATH)/$*.err ; fi
> @diff -u $(SRC_PATH)/$*.out $*.test.out
> @diff -u $(SRC_PATH)/$*.exit $*.test.exit
>
Huh?
[...]
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 04/49] qapi: pass 'if' condition into QAPISchemaEntity objects
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 04/49] qapi: pass 'if' condition into QAPISchemaEntity objects Marc-André Lureau
@ 2018-06-19 8:09 ` Markus Armbruster
0 siblings, 0 replies; 95+ messages in thread
From: Markus Armbruster @ 2018-06-19 8:09 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, armbru
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 wrapped type's generated for simple union variants,
Editing accident in v4: you changed "is the wrapper types" to "is the
wrapped type's" here instead of...
> 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
... changing "use wrapped type's" to "use the wrapped type's" here. Can
touch up on commit.
> simpler and good enough for now.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> Reviewed-by: Markus Armbruster <armbru@redhat.com>
R-by stands.
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 03/49] qapi: add 'if' to top-level expressions
2018-06-19 7:57 ` Markus Armbruster
@ 2018-06-19 8:41 ` Marc-André Lureau
2018-06-19 11:35 ` Markus Armbruster
0 siblings, 1 reply; 95+ messages in thread
From: Marc-André Lureau @ 2018-06-19 8:41 UTC (permalink / raw)
To: Markus Armbruster; +Cc: QEMU
On Tue, Jun 19, 2018 at 9:57 AM, Markus Armbruster <armbru@redhat.com> wrote:
> 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>
> [...]
>> diff --git a/tests/Makefile.include b/tests/Makefile.include
>> index 0b277036df..f77ad2ba3b 100644
>> --- a/tests/Makefile.include
>> +++ b/tests/Makefile.include
>> @@ -436,6 +436,10 @@ 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-if-list.json
>> qapi-schema += bad-type-bool.json
>> qapi-schema += bad-type-dict.json
>> qapi-schema += bad-type-int.json
>> @@ -933,6 +937,8 @@ $(patsubst %, check-%, $(check-qapi-schema-y)): check-%.json: $(SRC_PATH)/%.json
>> "TEST","$*.out")
>> @# Sanitize error messages (make them independent of build directory)
>> @perl -p -e 's|\Q$(SRC_PATH)\E/||g' $*.test.err | diff -u $(SRC_PATH)/$*.err -
>> + @if test "$(QAPI_REGENERATE)" == 1 ; then cp $*.test.out $(SRC_PATH)/$*.out ; fi
>> + @if test "$(QAPI_REGENERATE)" == 1 ; then cp $*.test.err $(SRC_PATH)/$*.err ; fi
>> @diff -u $(SRC_PATH)/$*.out $*.test.out
>> @diff -u $(SRC_PATH)/$*.exit $*.test.exit
>>
>
> Huh?
Oops, leftover. Do you have an alternative? I could propose it as a
seperate patch if it's generally useful.
--
Marc-André Lureau
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 05/49] qapi: leave the ifcond attribute undefined until check()
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 05/49] qapi: leave the ifcond attribute undefined until check() Marc-André Lureau
@ 2018-06-19 9:06 ` Markus Armbruster
2018-06-26 13:39 ` Marc-André Lureau
0 siblings, 1 reply; 95+ messages in thread
From: Markus Armbruster @ 2018-06-19 9:06 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, armbru
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> 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.
>
> Leave the ifcond attribute undefined until check().
Drawback: pylint complains. We'll live.
>
> Suggested-by: Markus Armbruster <armbru@redhat.com>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> Reviewed-by: Markus Armbruster <armbru@redhat.com>
Shouldn't this be squashed into the previous patch?
> ---
> scripts/qapi/common.py | 21 +++++++++++++++++----
> 1 file changed, 17 insertions(+), 4 deletions(-)
>
> diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
> index d8ab3d8f7f..eb07d641ab 100644
> --- a/scripts/qapi/common.py
> +++ b/scripts/qapi/common.py
> @@ -1026,13 +1026,19 @@ class QAPISchemaEntity(object):
> # such place).
> self.info = info
> self.doc = doc
> - self.ifcond = listify_cond(ifcond)
> + self._ifcond = ifcond # self.ifcond is set only after .check()
>
> def c_name(self):
> return c_name(self.name)
>
> def check(self, schema):
> - pass
> + if isinstance(self._ifcond, QAPISchemaType):
> + # inherit the condition from a type
> + typ = self._ifcond
> + typ.check(schema)
> + self.ifcond = typ.ifcond
> + else:
> + self.ifcond = listify_cond(self._ifcond)
Whenever we add a .check(), we need to prove QAPISchema.check()'s
recursion still terminates, and terminates the right way.
Argument before this patch: we recurse only into types contained in
types, e.g. an object type's base type, and we detect and report cycles
as "Object %s contains itself", in QAPISchemaObjectType.check().
The .check() added here recurses into a type. If this creates a cycle,
it'll be caught and reported as "contains itself". We still need to
show that the error message remains accurate.
We .check() here to inherit .ifcond from a type. As far as I can tell,
we use this inheritance feature only to inherit an array's condition
from its element type. That's safe, because an array does contain its
elements.
This is hardly a rigorous proof. Just enough to make me believe your
code works.
However, I suspect adding the inheritance feature at the entity level
complicates the correctness argument without real need. Can we restrict
it to array elements? Have QAPISchemaArrayType.check() resolve
type-valued ._ifcond, and all the others choke on it?
>
> def is_implicit(self):
> return not self.info
> @@ -1169,6 +1175,7 @@ class QAPISchemaEnumType(QAPISchemaType):
> self.prefix = prefix
>
> def check(self, schema):
> + QAPISchemaType.check(self, schema)
> seen = {}
> for v in self.values:
> v.check_clash(self.info, seen)
> @@ -1201,8 +1208,10 @@ class QAPISchemaArrayType(QAPISchemaType):
> self.element_type = None
>
> def check(self, schema):
> + QAPISchemaType.check(self, schema)
> self.element_type = schema.lookup_type(self._element_type_name)
> assert self.element_type
> + self.element_type.check(schema)
> self.ifcond = self.element_type.ifcond
>
> def is_implicit(self):
> @@ -1245,6 +1254,7 @@ class QAPISchemaObjectType(QAPISchemaType):
> self.members = None
>
> def check(self, schema):
> + QAPISchemaType.check(self, schema)
> if self.members is False: # check for cycles
> raise QAPISemError(self.info,
> "Object %s contains itself" % self.name)
> @@ -1427,6 +1437,7 @@ class QAPISchemaAlternateType(QAPISchemaType):
> self.variants = variants
>
> def check(self, schema):
> + QAPISchemaType.check(self, schema)
> self.variants.tag_member.check(schema)
> # Not calling self.variants.check_clash(), because there's nothing
> # to clash with
> @@ -1470,6 +1481,7 @@ class QAPISchemaCommand(QAPISchemaEntity):
> self.allow_oob = allow_oob
>
> def check(self, schema):
> + QAPISchemaEntity.check(self, schema)
> if self._arg_type_name:
> self.arg_type = schema.lookup_type(self._arg_type_name)
> assert (isinstance(self.arg_type, QAPISchemaObjectType) or
> @@ -1504,6 +1516,7 @@ class QAPISchemaEvent(QAPISchemaEntity):
> self.boxed = boxed
>
> def check(self, schema):
> + QAPISchemaEntity.check(self, schema)
> if self._arg_type_name:
> self.arg_type = schema.lookup_type(self._arg_type_name)
> assert (isinstance(self.arg_type, QAPISchemaObjectType) or
> @@ -1633,7 +1646,7 @@ class QAPISchema(object):
> # 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
> + assert ifcond == typ._ifcond
pylint complains
W:1649,29: Access to a protected member _ifcond of a client class (protected-access)
Layering violation. Tolerable, I think.
> else:
> self._def_entity(QAPISchemaObjectType(name, info, doc, ifcond,
> None, members, None))
> @@ -1679,7 +1692,7 @@ class QAPISchema(object):
> 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,
> + typ, info, None, self.lookup_type(typ),
> 'wrapper', [self._make_member('data', typ, info)])
> return QAPISchemaObjectTypeVariant(case, typ)
Perhaps other attributes that become valid only at .check() time should
receive the same treatment. Not necessarily in this series, not
necessarily by you. A TODO comment wouldn't hurt, though.
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 03/49] qapi: add 'if' to top-level expressions
2018-06-19 8:41 ` Marc-André Lureau
@ 2018-06-19 11:35 ` Markus Armbruster
0 siblings, 0 replies; 95+ messages in thread
From: Markus Armbruster @ 2018-06-19 11:35 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: Markus Armbruster, QEMU
Marc-André Lureau <marcandre.lureau@gmail.com> writes:
> On Tue, Jun 19, 2018 at 9:57 AM, Markus Armbruster <armbru@redhat.com> wrote:
>> 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>
>> [...]
>>> diff --git a/tests/Makefile.include b/tests/Makefile.include
>>> index 0b277036df..f77ad2ba3b 100644
>>> --- a/tests/Makefile.include
>>> +++ b/tests/Makefile.include
>>> @@ -436,6 +436,10 @@ 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-if-list.json
>>> qapi-schema += bad-type-bool.json
>>> qapi-schema += bad-type-dict.json
>>> qapi-schema += bad-type-int.json
>>> @@ -933,6 +937,8 @@ $(patsubst %, check-%, $(check-qapi-schema-y)): check-%.json: $(SRC_PATH)/%.json
>>> "TEST","$*.out")
>>> @# Sanitize error messages (make them independent of build directory)
>>> @perl -p -e 's|\Q$(SRC_PATH)\E/||g' $*.test.err | diff -u $(SRC_PATH)/$*.err -
>>> + @if test "$(QAPI_REGENERATE)" == 1 ; then cp $*.test.out $(SRC_PATH)/$*.out ; fi
>>> + @if test "$(QAPI_REGENERATE)" == 1 ; then cp $*.test.err $(SRC_PATH)/$*.err ; fi
>>> @diff -u $(SRC_PATH)/$*.out $*.test.out
>>> @diff -u $(SRC_PATH)/$*.exit $*.test.exit
>>>
>>
>> Huh?
>
> Oops, leftover. Do you have an alternative? I could propose it as a
> seperate patch if it's generally useful.
I guess what you're trying to do here is updating expected test output.
So far, everybody does that by hand.
A make target to do that (check-accept?) would be nice. Trivial to do
if we had a single test harness, but of course we have many.
My R-by stands with this hunk dropped.
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 24/49] qapi: add a dictionary form with 'type' key for members
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 24/49] qapi: add a dictionary form with 'type' key for members Marc-André Lureau
@ 2018-06-20 11:13 ` Markus Armbruster
0 siblings, 0 replies; 95+ messages in thread
From: Markus Armbruster @ 2018-06-20 11:13 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, armbru
No review, just a short note.
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Wherever a struct/union/alternate/command/event member with NAME: TYPE
> form is accepted, desugar it to a NAME: { 'type': TYPE } form.
>
> This will allow to add new member details, such as 'if' in the
> following patch to introduce conditionals, or 'default' for default
> values etc.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
[...]
> diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
> index 9eb2b0cc37..3f46ed5530 100644
> --- a/scripts/qapi/common.py
> +++ b/scripts/qapi/common.py
[...]
> @@ -952,6 +967,10 @@ def check_exprs(exprs):
> info = expr_elem['info']
> if 'enum' in expr:
> normalize_enum(expr, info)
> + elif 'union' in expr:
> + normalize_members(expr, 'base')
> + if {'union', 'alternate', 'struct', 'command', 'event'} & set(expr):
> + normalize_members(expr, 'data')
You've since changed this to
+ if set(['union', 'alternate', 'struct', 'command', 'event']) & set(expr):
+ normalize_members(expr, 'data')
in your git branch.
>
> # Learn the types and check for valid expression keys
> for expr_elem in exprs:
[...]
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 07/49] qapi: mcgen() shouldn't indent # lines
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 07/49] qapi: mcgen() shouldn't indent # lines Marc-André Lureau
@ 2018-06-20 15:14 ` Markus Armbruster
0 siblings, 0 replies; 95+ messages in thread
From: Markus Armbruster @ 2018-06-20 15:14 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, armbru
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/common.py | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
> index bc4ecd6c76..47efe79758 100644
> --- a/scripts/qapi/common.py
> +++ b/scripts/qapi/common.py
> @@ -1931,8 +1931,8 @@ 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),
> - indent + r'\g<0>', raw)
> + raw = re.subn(re.compile(r'^(?!(#|$))', re.MULTILINE),
> + indent, raw)
> raw = raw[0]
> return re.sub(re.escape(eatspace) + r' *', '', raw)
Reviewed-by: Markus Armbruster <armbru@redhat.com>
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 08/49] qapi: add #if/#endif helpers
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 08/49] qapi: add #if/#endif helpers Marc-André Lureau
@ 2018-06-20 16:01 ` Markus Armbruster
2018-06-21 7:06 ` Markus Armbruster
1 sibling, 0 replies; 95+ messages in thread
From: Markus Armbruster @ 2018-06-20 16:01 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, armbru
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Add helpers to wrap generated code with #if/#endif lines.
>
> Add QAPIGenCSnippet class to write C snippet code, make QAPIGenC
> inherit from it, for full C files with copyright headers etc.
>
> Add a 'with' statement context manager that will be used to wrap
> generator visitor methods. The manager will check if code was
> generated before adding #if/#endif lines on QAPIGenCSnippet
> objects. Used in the following patches.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi/common.py | 82 +++++++++++++++++++++++++++++++++++++++---
> 1 file changed, 78 insertions(+), 4 deletions(-)
>
> diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
> index 47efe79758..60c1d0a783 100644
> --- a/scripts/qapi/common.py
> +++ b/scripts/qapi/common.py
> @@ -12,6 +12,7 @@
> # See the COPYING file in the top-level directory.
>
> from __future__ import print_function
> +from contextlib import contextmanager
> import errno
> import os
> import re
> @@ -1964,6 +1965,40 @@ def guardend(name):
> name=guardname(name))
>
>
> +def gen_if(ifcond):
> + ret = ''
> + for ifc in ifcond:
> + ret += mcgen('''
> +#if %(cond)s
> +''', cond=ifc)
> + return ret
> +
> +
> +def gen_endif(ifcond):
> + ret = ''
> + for ifc in reversed(ifcond):
> + ret += mcgen('''
> +#endif /* %(cond)s */
> +''', cond=ifc)
> + return ret
> +
> +
> +def wrap_ifcond(ifcond, before, after):
Looks like a helper method. Name it _wrap_ifcond?
> + if ifcond is None or before == after:
> + return after
The before == after part suppresses empty conditionals. We'll see later
how we end up with them.
The ifcond is None part is suppresses "non-conditionals". I wonder how
that can happen.
Another non-conditional is []. Can that happen?
Questions like these indicate the function needs a contract.
> +
> + assert after.startswith(before)
> + out = before
> + added = after[len(before):]
> + if added[0] == '\n':
> + out += '\n'
> + added = added[1:]
The conditional adjusts vertical space around #if. This might need
tweaking, but let's not worry about that now.
> + out += gen_if(ifcond)
> + out += added
> + out += gen_endif(ifcond)
There's no similar adjustment for #endif. Again, let's not worry about
that now.
> + return out
> +
> +
> def gen_enum_lookup(name, values, prefix=None):
> ret = mcgen('''
>
> @@ -2054,6 +2089,7 @@ class QAPIGen(object):
> def __init__(self):
> self._preamble = ''
> self._body = ''
> + self._ifcond = None
>
> def preamble_add(self, text):
> self._preamble += text
> @@ -2061,6 +2097,23 @@ class QAPIGen(object):
> def add(self, text):
> self._body += text
>
> + def start_if(self, ifcond):
What are @ifcond's legal values? In particular, is it okay to pass
None?
If not, then we have an easy way to check whether we're between
.start_if() and .end_if(): ._ifcond is not None.
> + self._ifcond = ifcond
What if self._ifcond is not None?
Can happen only when you call .start_if within .start_if() ... .endif().
If that's not supposed to work, let's assert self._ifcond is None here,
and add a function contract spelling out the restriction.
> + self._start_if_body = self._body
> + self._start_if_preamble = self._preamble
> +
> + def _wrap_ifcond(self):
> + pass
> +
> + def end_if(self):
If .start_if() doesn't take None, then we can catch misuse of .end_if()
by asserting ._ifcond is not None here.
> + self._wrap_ifcond()
> + self._ifcond = None
I'd zap ._start_if_body and ._start_if_preamble here.
Note for later: use of .start_if() ... .end_if() has no effect unless
._wrap_ifcond() is overridden.
> +
> + def get_content(self, fname=None):
> + assert self._ifcond is None
> + return (self._top(fname) + self._preamble + self._body
> + + self._bottom(fname))
> +
> def _top(self, fname):
> return ''
>
> @@ -2078,8 +2131,7 @@ class QAPIGen(object):
> raise
> fd = os.open(pathname, os.O_RDWR | os.O_CREAT, 0o666)
> f = os.fdopen(fd, 'r+')
> - text = (self._top(fname) + self._preamble + self._body
> - + self._bottom(fname))
> + text = self.get_content(fname)
> oldtext = f.read(len(text) + 1)
> if text != oldtext:
> f.seek(0)
> @@ -2088,10 +2140,32 @@ class QAPIGen(object):
> f.close()
>
>
> -class QAPIGenC(QAPIGen):
> +@contextmanager
> +def ifcontext(ifcond, *args):
> + saved = []
> + for arg in args:
> + arg.start_if(ifcond)
> + yield
> + for arg in args:
> + arg.end_if()
@saved is write-only.
How to use the function isn't immediately obvious[*]; I had to glance at
later patches to be sure. Please add a function comment.
>
> - def __init__(self, blurb, pydoc):
> +
> +class QAPIGenCSnippet(QAPIGen):
> +
> + def __init__(self):
> QAPIGen.__init__(self)
> +
> + def _wrap_ifcond(self):
> + self._body = wrap_ifcond(self._ifcond,
> + self._start_if_body, self._body)
> + self._preamble = wrap_ifcond(self._ifcond,
> + self._start_if_preamble, self._preamble)
> +
> +
> +class QAPIGenC(QAPIGenCSnippet):
> +
> + def __init__(self, blurb, pydoc):
> + QAPIGenCSnippet.__init__(self)
> self._blurb = blurb
> self._copyright = '\n * '.join(re.findall(r'^Copyright .*', pydoc,
> re.MULTILINE))
Why do you need the intermediary class QAPIGenCSnippet?
As far as I can see, only one subclass overrides ._wrap_ifcond(). Why
is the general machinery in the superclass, where it does nothing, and
not in the subclass that makes it do something?
[*] Compared to the decorator you had in v4, it's simple as pie.
There *had* to be a better way, and it looks like you found one.
Appreciated!
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 08/49] qapi: add #if/#endif helpers
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 08/49] qapi: add #if/#endif helpers Marc-André Lureau
2018-06-20 16:01 ` Markus Armbruster
@ 2018-06-21 7:06 ` Markus Armbruster
1 sibling, 0 replies; 95+ messages in thread
From: Markus Armbruster @ 2018-06-21 7:06 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, armbru
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Add helpers to wrap generated code with #if/#endif lines.
>
> Add QAPIGenCSnippet class to write C snippet code, make QAPIGenC
> inherit from it, for full C files with copyright headers etc.
>
> Add a 'with' statement context manager that will be used to wrap
> generator visitor methods. The manager will check if code was
> generated before adding #if/#endif lines on QAPIGenCSnippet
> objects. Used in the following patches.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi/common.py | 82 +++++++++++++++++++++++++++++++++++++++---
> 1 file changed, 78 insertions(+), 4 deletions(-)
>
> diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
> index 47efe79758..60c1d0a783 100644
> --- a/scripts/qapi/common.py
> +++ b/scripts/qapi/common.py
[...]
> @@ -2061,6 +2097,23 @@ class QAPIGen(object):
> def add(self, text):
> self._body += text
>
> + def start_if(self, ifcond):
> + self._ifcond = ifcond
> + self._start_if_body = self._body
> + self._start_if_preamble = self._preamble
pylint gripes:
+W:2102, 8: Attribute '_start_if_body' defined outside __init__ (attribute-defined-outside-init)
+W:2103, 8: Attribute '_start_if_preamble' defined outside __init__ (attribute-defined-outside-init)
We generally define in .__init__(), except when we want to catch
premature use, such as in PATCH 05. Let's define these two in
.__init__().
[...]
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 06/49] qapi: add 'ifcond' to visitor methods
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 06/49] qapi: add 'ifcond' to visitor methods Marc-André Lureau
@ 2018-06-21 8:18 ` Markus Armbruster
0 siblings, 0 replies; 95+ messages in thread
From: Markus Armbruster @ 2018-06-21 8:18 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, armbru
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>
> ---
[...]
> diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
> index 10e68b01d9..6d25a37dda 100644
> --- a/tests/qapi-schema/test-qapi.py
> +++ b/tests/qapi-schema/test-qapi.py
> @@ -23,12 +23,13 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
> def visit_include(self, name, info):
> print('include %s' % name)
>
> - 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)
> @@ -36,21 +37,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, allow_oob):
> 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):
> @@ -59,6 +64,10 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
> for v in variants.variants:
> print(' case %s: %s' % (v.name, v.type.name))
>
> + @staticmethod
> + def _print_if(ifcond, indent=4):
> + if ifcond:
> + print('%sif %s' % (' ' * indent, ifcond))
>
pycodestyle points out:
tests/qapi-schema/test-qapi.py:72:1: E305 expected 2 blank lines after class or function definition, found 1
Can touch up when I apply.
> try:
> schema = QAPISchema(sys.argv[1])
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 10/49] qapi-introspect: add preprocessor conditions to generated QLit
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 10/49] qapi-introspect: add preprocessor conditions to generated QLit Marc-André Lureau
@ 2018-06-21 13:05 ` Markus Armbruster
0 siblings, 0 replies; 95+ messages in thread
From: Markus Armbruster @ 2018-06-21 13:05 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, armbru
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> The generator will take (obj, condition) tuples to wrap generated QLit
> objects for 'obj' with #if/#endif conditions.
>
> This commit adds 'ifcond' condition to top-level QLit objects.
>
> See generated tests/test-qmp-introspect.c. Example diff after this patch:
>
> --- before 2018-01-08 11:55:24.757083654 +0100
> +++ tests/test-qmp-introspect.c 2018-01-08 13:08:44.477641629 +0100
> @@ -51,6 +51,8 @@
> { "name", QLIT_QSTR("EVENT_F"), },
> {}
> })),
> +#if defined(TEST_IF_CMD)
> +#if defined(TEST_IF_STRUCT)
> QLIT_QDICT(((QLitDictEntry[]) {
> { "arg-type", QLIT_QSTR("5"), },
> { "meta-type", QLIT_QSTR("command"), },
> @@ -58,12 +60,16 @@
> { "ret-type", QLIT_QSTR("0"), },
> {}
> })),
> +#endif /* defined(TEST_IF_STRUCT) */
> +#endif /* defined(TEST_IF_CMD) */
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi/introspect.py | 31 +++++++++++++++++++++----------
> 1 file changed, 21 insertions(+), 10 deletions(-)
>
> diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
> index 1a8eb9e33e..cb4825f134 100644
> --- a/scripts/qapi/introspect.py
> +++ b/scripts/qapi/introspect.py
> @@ -18,6 +18,15 @@ 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)
> + endif = gen_endif(ifcond)
> + if endif:
> + ret += '\n' + endif
> + return ret
> +
> ret = ''
> if not suppress_first_indent:
> ret += indent(level)
@obj represents a JSON object. It consists of dictionaries, lists,
strings, booleans and None. Numbers aren't implemented. Your patch
splices in tuples to represent conditionals at any level.
So far, tuples occur only as elements of the outermost list (see
._gen_qlit() below), but to_qlit() supports them anywhere. I figure
that will be needed later. If yes, the whole thing is a bit of a hack,
but at least it's a simple hack. If no, I'd look for a solution that
feels less hackish.
By the way, this hunk makes my pylint die with "RecursionError: maximum
recursion depth exceeded". If I comment out the line with the
recursion, it survives. Latest git survives, too. Oh well, python3
setup.py install.
> @@ -26,7 +35,7 @@ def to_qlit(obj, level=0, suppress_first_indent=False):
> elif isinstance(obj, str):
> ret += 'QLIT_QSTR(' + to_c_string(obj) + ')'
> elif isinstance(obj, list):
> - elts = [to_qlit(elt, level + 1)
> + elts = [to_qlit(elt, level + 1).strip('\n')
> for elt in obj]
> elts.append(indent(level + 1) + "{}")
> ret += 'QLIT_QLIST(((QLitObject[]) {\n'
The .strip('\n') looks odd. Reminds me of the asymmetry I noted in
PATCH 08: you take care to adjust vertical space around #if there, but
not around #endif. Let's not worry about it now.
> @@ -131,12 +140,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))
This is where we produce ._qlits. It's also the only place where we
create tuples. Thus, all elements of ._qlits are tuples, and no tuples
occur at deeper levels.
>
> def _gen_member(self, member):
> ret = {'name': member.name, 'type': self._use_type(member.type)}
> @@ -152,26 +161,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}, [])
>
> 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, allow_oob):
> @@ -180,11 +190,12 @@ const QLitObject %(c_name)s = %(c_string)s;
> self._gen_qlit(name, 'command',
> {'arg-type': self._use_type(arg_type),
> 'ret-type': self._use_type(ret_type),
> - 'allow-oob': allow_oob})
> + 'allow-oob': allow_oob}, 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)
>
>
> def gen_introspect(schema, output_dir, prefix, opt_unmask):
I still prefer the approach I explored in
[PATCH RFC 09/14] qapi: Pass ifcond to visitors
[PATCH RFC 13/14] qapi-introspect: Add #if conditions to introspection value
because it separates the concerns. I'd love to complete my exploration
so we can compare apples to apples. However, with the soft freeze
closing in, I'll probably have to take the solution that's already
complete, regardless of my preference.
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 11/49] qapi/commands: add #if conditions to commands
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 11/49] qapi/commands: add #if conditions to commands Marc-André Lureau
@ 2018-06-21 14:35 ` Markus Armbruster
2018-06-22 8:34 ` Markus Armbruster
1 sibling, 0 replies; 95+ messages in thread
From: Markus Armbruster @ 2018-06-21 14:35 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, armbru
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Wrap generated code with #if/#endif using an 'ifcontext' on
> QAPIGenCSnippet objects.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi/commands.py | 19 ++++++++++---------
> tests/test-qmp-cmds.c | 4 ++--
> 2 files changed, 12 insertions(+), 11 deletions(-)
>
> diff --git a/scripts/qapi/commands.py b/scripts/qapi/commands.py
> index e2366b4801..40bb680b7c 100644
> --- a/scripts/qapi/commands.py
> +++ b/scripts/qapi/commands.py
> @@ -237,7 +237,7 @@ class QAPISchemaGenCommandVisitor(QAPISchemaModularCVisitor):
> QAPISchemaModularCVisitor.__init__(
> self, prefix, 'qapi-commands',
> ' * Schema-defined QAPI/QMP commands', __doc__)
> - self._regy = ''
> + self._regy = QAPIGenCSnippet()
Aha, here's the answer to my question on PATCH 08: you need
QAPIGenCSnippet...
> self._visited_ret_types = {}
>
> def _begin_module(self, name):
> @@ -273,19 +273,20 @@ class QAPISchemaGenCommandVisitor(QAPISchemaModularCVisitor):
> void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds);
> ''',
> c_prefix=c_name(self._prefix, protect=False)))
> - genc.add(gen_registry(self._regy, self._prefix))
> + genc.add(gen_registry(self._regy.get_content(), self._prefix))
>
> def visit_command(self, name, info, ifcond, arg_type, ret_type,
> gen, success_response, boxed, allow_oob):
> if not gen:
> return
> - self._genh.add(gen_command_decl(name, arg_type, boxed, ret_type))
> - if ret_type and ret_type not in self._visited_ret_types[self._genc]:
> - self._visited_ret_types[self._genc].add(ret_type)
> - self._genc.add(gen_marshal_output(ret_type))
> - self._genh.add(gen_marshal_decl(name))
> - self._genc.add(gen_marshal(name, arg_type, boxed, ret_type))
> - self._regy += gen_register_command(name, success_response, allow_oob)
> + with ifcontext(ifcond, self._genh, self._genc, self._regy):
... so you can pass ._regy to with ifcontext.
The name QAPIGenCSnippet makes sense for this role. Less so for its
role as base class of QAPIGenC. Dunno... QAPIGenCCode?
> + self._genh.add(gen_command_decl(name, arg_type, boxed, ret_type))
> + if ret_type and ret_type not in self._visited_ret_types[self._genc]:
pycodestyle-3 reports
commands.py:284:80: E501 line too long (80 > 79 characters)
> + self._visited_ret_types[self._genc].add(ret_type)
> + self._genc.add(gen_marshal_output(ret_type))
> + self._genh.add(gen_marshal_decl(name))
> + self._genc.add(gen_marshal(name, arg_type, boxed, ret_type))
> + self._regy.add(gen_register_command(name, success_response, allow_oob))
pycodestyle-3 reports
commands.py:289:80: E501 line too long (83 > 79 characters)
>
>
> def gen_commands(schema, output_dir, prefix):
> diff --git a/tests/test-qmp-cmds.c b/tests/test-qmp-cmds.c
> index c25fc2100a..e675722593 100644
> --- a/tests/test-qmp-cmds.c
> +++ b/tests/test-qmp-cmds.c
> @@ -12,11 +12,11 @@
>
> static QmpCommandList qmp_commands;
>
> -/* #if defined(TEST_IF_STRUCT) && defined(TEST_IF_CMD) */
> +#if defined(TEST_IF_STRUCT) && defined(TEST_IF_CMD)
> void qmp_TestIfCmd(TestIfStruct *foo, Error **errp)
> {
> }
> -/* #endif */
> +#endif
>
> void qmp_user_def_cmd(Error **errp)
> {
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 12/49] qapi/events: add #if conditions to events
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 12/49] qapi/events: add #if conditions to events Marc-André Lureau
@ 2018-06-21 14:40 ` Markus Armbruster
2018-06-22 9:02 ` Markus Armbruster
1 sibling, 0 replies; 95+ messages in thread
From: Markus Armbruster @ 2018-06-21 14:40 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, armbru
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Wrap generated code with #if/#endif using an 'ifcontext' on
> QAPIGenCSnippet objects.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi/events.py | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/scripts/qapi/events.py b/scripts/qapi/events.py
> index 26ae00f6f7..dae03e3d88 100644
> --- a/scripts/qapi/events.py
> +++ b/scripts/qapi/events.py
> @@ -185,8 +185,9 @@ class QAPISchemaGenEventVisitor(QAPISchemaModularCVisitor):
> genc.add(gen_enum_lookup(self._enum_name, self._event_names))
>
> def visit_event(self, name, info, ifcond, arg_type, boxed):
> - self._genh.add(gen_event_send_decl(name, arg_type, boxed))
> - self._genc.add(gen_event_send(name, arg_type, boxed, self._enum_name))
> + with ifcontext(ifcond, self._genh, self._genc):
> + self._genh.add(gen_event_send_decl(name, arg_type, boxed))
> + self._genc.add(gen_event_send(name, arg_type, boxed, self._enum_name))
events.py:190:80: E501 line too long (82 > 79 characters)
> self._event_names.append(name)
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 13/49] qapi-types: refactor variants handling
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 13/49] qapi-types: refactor variants handling Marc-André Lureau
@ 2018-06-21 15:54 ` Markus Armbruster
0 siblings, 0 replies; 95+ messages in thread
From: Markus Armbruster @ 2018-06-21 15:54 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, armbru
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.
ifcond_decorator is no more, please update your commit message.
>
> gen_variants_objects() calls gen_object() for each variants, so it
s/for each variants/for each variant/
> remains guarded for each generated variant object.
>
> self._gen_type_cleanup(name) is factored out in _gen_object(), helping
> generated code to be wrapped by the same condition in the following
> patch.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
I read this thrice, and I still fail to understand the second and third
paragraph.
I'm skipping this patch for now, because we might not need it; see
review of next patch.
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 14/49] qapi-types: add #if conditions to types & visitors
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 14/49] qapi-types: add #if conditions to types & visitors Marc-André Lureau
@ 2018-06-21 16:12 ` Markus Armbruster
2018-06-27 11:59 ` Marc-André Lureau
0 siblings, 1 reply; 95+ messages in thread
From: Markus Armbruster @ 2018-06-21 16:12 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Types & visitors are coupled and must be handled together to avoid
> temporary build regression.
>
> Wrap generated types/visitor code with #if/#endif using the context
> helpers.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi/types.py | 46 ++++++++++++++++++++++++++-----------------
> scripts/qapi/visit.py | 33 ++++++++++++++++++-------------
> 2 files changed, 47 insertions(+), 32 deletions(-)
>
> diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py
> index 3d9b0f9a07..ce4c91206c 100644
> --- a/scripts/qapi/types.py
> +++ b/scripts/qapi/types.py
> @@ -61,8 +61,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)
Ignorant question out of curiosity, why is with ifcontext() not usable
here?
> return ret
>
>
> @@ -206,41 +208,49 @@ class QAPISchemaGenTypeVisitor(QAPISchemaModularCVisitor):
> # gen_object() is recursive, ensure it doesn't visit the empty type
> objects_seen.add(schema.the_empty_object_type.name)
>
> - def _gen_type_cleanup(self, name):
> - self._genh.add(gen_type_cleanup_decl(name))
> - self._genc.add(gen_type_cleanup(name))
> + def _gen_type_cleanup(self, name, ifcond):
> + with ifcontext(ifcond, self._genh, self._genc):
> + self._genh.add(gen_type_cleanup_decl(name))
> + self._genc.add(gen_type_cleanup(name))
>
> def visit_enum_type(self, name, info, ifcond, values, prefix):
> - self._genh.preamble_add(gen_enum(name, values, prefix))
> - self._genc.add(gen_enum_lookup(name, values, prefix))
> + with ifcontext(ifcond, self._genh, self._genc):
> + self._genh.preamble_add(gen_enum(name, values, prefix))
> + self._genc.add(gen_enum_lookup(name, values, prefix))
>
> def visit_array_type(self, name, info, ifcond, element_type):
> - self._genh.preamble_add(gen_fwd_object_or_array(name))
> - self._genh.add(gen_array(name, element_type))
> - self._gen_type_cleanup(name)
> + with ifcontext(ifcond, self._genh):
> + self._genh.preamble_add(gen_fwd_object_or_array(name))
> + self._genh.add(gen_array(name, element_type))
> + self._gen_type_cleanup(name, ifcond)
>
> def _gen_object(self, name, info, ifcond, base, members, variants):
> - self._genh.add(gen_object(name, base, members, variants))
> - if base and not base.is_implicit():
> - self._genh.add(gen_upcast(name, base))
> - # TODO Worth changing the visitor signature, so we could
> - # directly use rather than repeat type.is_implicit()?
> + with ifcontext(ifcond, self._genh):
> + self._genh.add(gen_object(name, base, members, variants))
> + if base and not base.is_implicit():
> + self._genh.add(gen_upcast(name, base))
> + # TODO Worth changing the visitor signature, so we could
> + # directly use rather than repeat type.is_implicit()?
> if not name.startswith('q_'):
> # implicit types won't be directly allocated/freed
> - self._gen_type_cleanup(name)
> + self._gen_type_cleanup(name, ifcond)
> +
> + def _gen_fwd_object_or_array(self, name, ifcond):
> + with ifcontext(ifcond, self._genh):
> + self._genh.preamble_add(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._genh.preamble_add(gen_fwd_object_or_array(name))
> + self._gen_fwd_object_or_array(name, ifcond)
> self._genh.add(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._genh.preamble_add(gen_fwd_object_or_array(name))
> + self._gen_fwd_object_or_array(name, ifcond)
> self._genh.add(gen_variants_objects(variants))
> - self._gen_object(name, info, None, None,
> + self._gen_object(name, info, ifcond, None,
> [variants.tag_member], variants)
>
>
> diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py
> index 9ea2e04f81..e4a62ce030 100644
> --- a/scripts/qapi/visit.py
> +++ b/scripts/qapi/visit.py
> @@ -302,29 +302,34 @@ class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor):
> types=types))
>
> def visit_enum_type(self, name, info, ifcond, values, prefix):
> - self._genh.add(gen_visit_decl(name, scalar=True))
> - self._genc.add(gen_visit_enum(name))
> + with ifcontext(ifcond, self._genh, self._genc):
> + self._genh.add(gen_visit_decl(name, scalar=True))
> + self._genc.add(gen_visit_enum(name))
>
> def visit_array_type(self, name, info, ifcond, element_type):
> - self._genh.add(gen_visit_decl(name))
> - self._genc.add(gen_visit_list(name, element_type))
> + with ifcontext(ifcond, self._genh, self._genc):
> + self._genh.add(gen_visit_decl(name))
> + self._genc.add(gen_visit_list(name, element_type))
>
> 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._genh.add(gen_visit_members_decl(name))
> - self._genc.add(gen_visit_object_members(name, base, members, variants))
> - # TODO Worth changing the visitor signature, so we could
> - # directly use rather than repeat type.is_implicit()?
> - if not name.startswith('q_'):
> - # only explicit types need an allocating visit
> - self._genh.add(gen_visit_decl(name))
> - self._genc.add(gen_visit_object(name, base, members, variants))
> + with ifcontext(ifcond, self._genh, self._genc):
> + self._genh.add(gen_visit_members_decl(name))
> + self._genc.add(gen_visit_object_members(name, base,
> + members, variants))
> + # TODO Worth changing the visitor signature, so we could
> + # directly use rather than repeat type.is_implicit()?
> + if not name.startswith('q_'):
> + # only explicit types need an allocating visit
> + self._genh.add(gen_visit_decl(name))
> + self._genc.add(gen_visit_object(name, base, members, variants))
>
> def visit_alternate_type(self, name, info, ifcond, variants):
> - self._genh.add(gen_visit_decl(name))
> - self._genc.add(gen_visit_alternate(name, variants))
> + with ifcontext(ifcond, self._genh, self._genc):
> + self._genh.add(gen_visit_decl(name))
> + self._genc.add(gen_visit_alternate(name, variants))
>
>
> def gen_visit(schema, output_dir, prefix, opt_builtins):
The visit part is straightforward: wrap code generation in with
ifcontext().
The type part is more involved. First, it passes ifcond to a bunch of
helpers, which muddies the waters a bit. Second, you can't just wrap
object types generation, because it's recursive. You move the recursion
out of gen_object() (previous patch), so you can wrap that. But you
still can't wrap its new home, gen_variants_objects(). Instead, you
bracket its call of gen_object() with gen_if() ... gen_endif(). Works,
but is there a more direct path to the same result?
I append my attempt. Its basic idea is to wrap code generation right
where it is. Requires passing ifcond to gen_object(). The patch to
visit.py is identical.
Less churn, and I it saves me reviewing the previous patch. Opinions?
>From d6f26abe5a81b10aaff5c75db3bfc60c05203f05 Mon Sep 17 00:00:00 2001
From: Markus Armbruster <armbru@redhat.com>
Date: Thu, 21 Jun 2018 18:03:41 +0200
Subject: [PATCH] qapi-types: add #if conditions to types & visitors
Types & visitors are coupled and must be handled together to avoid
temporary build regression.
Wrap generated types/visitor code with #if/#endif using the context
helpers.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
scripts/qapi/types.py | 48 ++++++++++++++++++++++++++-----------------
scripts/qapi/visit.py | 33 ++++++++++++++++-------------
2 files changed, 48 insertions(+), 33 deletions(-)
diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py
index 298a80db62..e43138bfd7 100644
--- a/scripts/qapi/types.py
+++ b/scripts/qapi/types.py
@@ -55,7 +55,7 @@ def gen_struct_members(members):
return ret
-def gen_object(name, base, members, variants):
+def gen_object(name, ifcond, base, members, variants):
if name in objects_seen:
return ''
objects_seen.add(name)
@@ -64,11 +64,14 @@ def gen_object(name, base, members, variants):
if variants:
for v in variants.variants:
if isinstance(v.type, QAPISchemaObjectType):
- ret += gen_object(v.type.name, v.type.base,
+ ret += gen_object(v.type.name, v.type.ifcond, v.type.base,
v.type.local_members, v.type.variants)
ret += mcgen('''
+''')
+ ret += gen_if(ifcond)
+ ret += mcgen('''
struct %(c_name)s {
''',
c_name=c_name(name))
@@ -101,6 +104,7 @@ struct %(c_name)s {
ret += mcgen('''
};
''')
+ ret += gen_endif(ifcond)
return ret
@@ -207,33 +211,39 @@ class QAPISchemaGenTypeVisitor(QAPISchemaModularCVisitor):
self._genc.add(gen_type_cleanup(name))
def visit_enum_type(self, name, info, ifcond, values, prefix):
- self._genh.preamble_add(gen_enum(name, values, prefix))
- self._genc.add(gen_enum_lookup(name, values, prefix))
+ with ifcontext(ifcond, self._genh, self._genc):
+ self._genh.preamble_add(gen_enum(name, values, prefix))
+ self._genc.add(gen_enum_lookup(name, values, prefix))
def visit_array_type(self, name, info, ifcond, element_type):
- self._genh.preamble_add(gen_fwd_object_or_array(name))
- self._genh.add(gen_array(name, element_type))
- self._gen_type_cleanup(name)
+ with ifcontext(ifcond, self._genh, self._genc):
+ self._genh.preamble_add(gen_fwd_object_or_array(name))
+ self._genh.add(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._genh.preamble_add(gen_fwd_object_or_array(name))
- self._genh.add(gen_object(name, base, members, variants))
- if base and not base.is_implicit():
- self._genh.add(gen_upcast(name, base))
- # TODO Worth changing the visitor signature, so we could
- # directly use rather than repeat type.is_implicit()?
- if not name.startswith('q_'):
- # implicit types won't be directly allocated/freed
- self._gen_type_cleanup(name)
+ with ifcontext(ifcond, self._genh):
+ self._genh.preamble_add(gen_fwd_object_or_array(name))
+ self._genh.add(gen_object(name, ifcond, base, members, variants))
+ with ifcontext(ifcond, self._genh, self._genc):
+ if base and not base.is_implicit():
+ self._genh.add(gen_upcast(name, base))
+ # TODO Worth changing the visitor signature, so we could
+ # directly use rather than repeat type.is_implicit()?
+ if not name.startswith('q_'):
+ # implicit types won't be directly allocated/freed
+ self._gen_type_cleanup(name)
def visit_alternate_type(self, name, info, ifcond, variants):
- self._genh.preamble_add(gen_fwd_object_or_array(name))
- self._genh.add(gen_object(name, None,
+ with ifcontext(ifcond, self._genh):
+ self._genh.preamble_add(gen_fwd_object_or_array(name))
+ self._genh.add(gen_object(name, ifcond, None,
[variants.tag_member], variants))
- self._gen_type_cleanup(name)
+ with ifcontext(ifcond, self._genh, self._genc):
+ self._gen_type_cleanup(name)
def gen_types(schema, output_dir, prefix, opt_builtins):
diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py
index 9ea2e04f81..e4a62ce030 100644
--- a/scripts/qapi/visit.py
+++ b/scripts/qapi/visit.py
@@ -302,29 +302,34 @@ class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor):
types=types))
def visit_enum_type(self, name, info, ifcond, values, prefix):
- self._genh.add(gen_visit_decl(name, scalar=True))
- self._genc.add(gen_visit_enum(name))
+ with ifcontext(ifcond, self._genh, self._genc):
+ self._genh.add(gen_visit_decl(name, scalar=True))
+ self._genc.add(gen_visit_enum(name))
def visit_array_type(self, name, info, ifcond, element_type):
- self._genh.add(gen_visit_decl(name))
- self._genc.add(gen_visit_list(name, element_type))
+ with ifcontext(ifcond, self._genh, self._genc):
+ self._genh.add(gen_visit_decl(name))
+ self._genc.add(gen_visit_list(name, element_type))
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._genh.add(gen_visit_members_decl(name))
- self._genc.add(gen_visit_object_members(name, base, members, variants))
- # TODO Worth changing the visitor signature, so we could
- # directly use rather than repeat type.is_implicit()?
- if not name.startswith('q_'):
- # only explicit types need an allocating visit
- self._genh.add(gen_visit_decl(name))
- self._genc.add(gen_visit_object(name, base, members, variants))
+ with ifcontext(ifcond, self._genh, self._genc):
+ self._genh.add(gen_visit_members_decl(name))
+ self._genc.add(gen_visit_object_members(name, base,
+ members, variants))
+ # TODO Worth changing the visitor signature, so we could
+ # directly use rather than repeat type.is_implicit()?
+ if not name.startswith('q_'):
+ # only explicit types need an allocating visit
+ self._genh.add(gen_visit_decl(name))
+ self._genc.add(gen_visit_object(name, base, members, variants))
def visit_alternate_type(self, name, info, ifcond, variants):
- self._genh.add(gen_visit_decl(name))
- self._genc.add(gen_visit_alternate(name, variants))
+ with ifcontext(ifcond, self._genh, self._genc):
+ self._genh.add(gen_visit_decl(name))
+ self._genc.add(gen_visit_alternate(name, variants))
def gen_visit(schema, output_dir, prefix, opt_builtins):
--
2.17.1
^ permalink raw reply related [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 31/49] qapi2texi: add 'If:' section to generated documentation
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 31/49] qapi2texi: add 'If:' section to generated documentation Marc-André Lureau
@ 2018-06-21 16:29 ` Markus Armbruster
0 siblings, 0 replies; 95+ messages in thread
From: Markus Armbruster @ 2018-06-21 16:29 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, armbru
Subject needs an update for the move of qapi2texi.py to do qapi/doc.py.
I think just qapi: would be fine.
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.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi/doc.py | 22 ++++++++++++----------
> tests/qapi-schema/doc-good.json | 2 +-
> tests/qapi-schema/doc-good.out | 1 +
> tests/qapi-schema/doc-good.texi | 2 ++
> 4 files changed, 16 insertions(+), 11 deletions(-)
>
> diff --git a/scripts/qapi/doc.py b/scripts/qapi/doc.py
> index 6c2bf98e1d..783b13303a 100755
> --- a/scripts/qapi/doc.py
> +++ b/scripts/qapi/doc.py
> @@ -174,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:
> @@ -185,14 +185,16 @@ def texi_sections(doc):
> body += texi_example(section.text)
> else:
> body += texi_format(section.text)
> + if ifcond:
> + body += '\n\n@b{If:} @code{%s}' % ", ".join(ifcond)
This is the actual change. The other hunks for this file are about
passing @ifcond to this spot.
I figure we should explain 'If:' in the introduction, i.e. the big
comment in qapi-schema.json. Since we fail to explain any of the other
tags there, this is somebody else's problem.
> 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.common.QAPISchemaVisitor):
> @@ -208,7 +210,7 @@ class QAPISchemaGenDocVisitor(qapi.common.QAPISchemaVisitor):
> doc = self.cur_doc
> self._gen.add(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):
> @@ -217,14 +219,14 @@ class QAPISchemaGenDocVisitor(qapi.common.QAPISchemaVisitor):
> base = None
> self._gen.add(TYPE_FMT(type='Object',
> name=doc.symbol,
> - body=texi_entity(doc, 'Members',
> + body=texi_entity(doc, 'Members', ifcond,
> base, variants)))
>
> def visit_alternate_type(self, name, info, ifcond, variants):
> doc = self.cur_doc
> self._gen.add(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, allow_oob):
> @@ -233,9 +235,9 @@ class QAPISchemaGenDocVisitor(qapi.common.QAPISchemaVisitor):
> body = texi_body(doc)
> body += ('\n@b{Arguments:} the members of @code{%s}\n'
> % 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._gen.add(MSG_FMT(type='Command',
> name=doc.symbol,
> body=body))
> @@ -244,7 +246,7 @@ class QAPISchemaGenDocVisitor(qapi.common.QAPISchemaVisitor):
> doc = self.cur_doc
> self._gen.add(MSG_FMT(type='Event',
> name=doc.symbol,
> - body=texi_entity(doc, 'Arguments')))
> + body=texi_entity(doc, 'Arguments', ifcond)))
>
> def symbol(self, doc, entity):
> if self._gen._body:
> @@ -257,7 +259,7 @@ class QAPISchemaGenDocVisitor(qapi.common.QAPISchemaVisitor):
> assert not doc.args
> if self._gen._body:
> self._gen.add('\n')
> - self._gen.add(texi_body(doc) + texi_sections(doc))
> + self._gen.add(texi_body(doc) + texi_sections(doc, None))
>
>
> def gen_doc(schema, output_dir, prefix):
> diff --git a/tests/qapi-schema/doc-good.json b/tests/qapi-schema/doc-good.json
> index 97ab4625ff..984cd8ed06 100644
> --- a/tests/qapi-schema/doc-good.json
> +++ b/tests/qapi-schema/doc-good.json
> @@ -55,7 +55,7 @@
> #
> # @two is undocumented
> ##
> -{ 'enum': 'Enum', 'data': [ 'one', 'two' ] }
> +{ 'enum': 'Enum', 'data': [ 'one', 'two' ], 'if': 'defined(IFCOND)' }
>
> ##
> # @Base:
> diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out
> index 3cd5c094aa..e4054e293c 100644
> --- a/tests/qapi-schema/doc-good.out
> +++ b/tests/qapi-schema/doc-good.out
> @@ -12,6 +12,7 @@ module doc-good.json
> enum Enum
> member one
> member two
> + if ['defined(IFCOND)']
> object Base
> member base1: Enum optional=False
> object Variant1
> diff --git a/tests/qapi-schema/doc-good.texi b/tests/qapi-schema/doc-good.texi
> index 0aed2300a5..e42eace474 100644
> --- a/tests/qapi-schema/doc-good.texi
> +++ b/tests/qapi-schema/doc-good.texi
> @@ -89,6 +89,8 @@ Not documented
> @end table
> @code{two} is undocumented
>
> +
> +@b{If:} @code{defined(IFCOND)}
> @end deftp
Test coverage is a bit sparse, but it'll do for now.
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
` (52 preceding siblings ...)
2018-03-22 5:11 ` no-reply
@ 2018-06-21 16:47 ` Markus Armbruster
2018-06-21 17:18 ` Marc-André Lureau
53 siblings, 1 reply; 95+ messages in thread
From: Markus Armbruster @ 2018-06-21 16:47 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel
I think we can bite off a digestible part of this series:
target-independent top-level conditionals. I think that's PATCH
01-14,31 and applicable parts of 35-37. The idea is to merge that part
quickly, then deal with the (less daunting) remainder. Marc-André, if
you agree with that plan, please respin just that part. I can continue
review of the remainder without a rebase.
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code
2018-06-21 16:47 ` Markus Armbruster
@ 2018-06-21 17:18 ` Marc-André Lureau
2018-06-22 6:56 ` Markus Armbruster
2018-06-22 9:06 ` Markus Armbruster
0 siblings, 2 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-06-21 17:18 UTC (permalink / raw)
To: Markus Armbruster; +Cc: QEMU
Hi
On Thu, Jun 21, 2018 at 6:47 PM, Markus Armbruster <armbru@redhat.com> wrote:
> I think we can bite off a digestible part of this series:
> target-independent top-level conditionals. I think that's PATCH
> 01-14,31 and applicable parts of 35-37. The idea is to merge that part
> quickly, then deal with the (less daunting) remainder. Marc-André, if
> you agree with that plan, please respin just that part. I can continue
> review of the remainder without a rebase.
>
That's ok with me, I'll work on it.
thanks
--
Marc-André Lureau
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code
2018-06-21 17:18 ` Marc-André Lureau
@ 2018-06-22 6:56 ` Markus Armbruster
2018-06-22 9:06 ` Markus Armbruster
1 sibling, 0 replies; 95+ messages in thread
From: Markus Armbruster @ 2018-06-22 6:56 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: Markus Armbruster, QEMU
Marc-André Lureau <marcandre.lureau@gmail.com> writes:
> Hi
>
> On Thu, Jun 21, 2018 at 6:47 PM, Markus Armbruster <armbru@redhat.com> wrote:
>> I think we can bite off a digestible part of this series:
>> target-independent top-level conditionals. I think that's PATCH
>> 01-14,31 and applicable parts of 35-37. The idea is to merge that part
>> quickly, then deal with the (less daunting) remainder. Marc-André, if
>> you agree with that plan, please respin just that part. I can continue
>> review of the remainder without a rebase.
>>
>
> That's ok with me, I'll work on it.
> thanks
Great!
The next part could be target-dependend top-level conditionals, or
member conditionals (enum members are tied to union variants, which may
make further splitting impractical). This series does members first. I
guess we stick to that order to avoid unnecessary patch reordering work.
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 15/49] qapi: do not define enumeration value explicitely
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 15/49] qapi: do not define enumeration value explicitely Marc-André Lureau
@ 2018-06-22 8:08 ` Markus Armbruster
2018-06-27 12:13 ` Marc-André Lureau
0 siblings, 1 reply; 95+ messages in thread
From: Markus Armbruster @ 2018-06-22 8:08 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, armbru
Subject: explicitly
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/common.py | 7 ++-----
> 1 file changed, 2 insertions(+), 5 deletions(-)
>
> diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
> index 60c1d0a783..68a567f53f 100644
> --- a/scripts/qapi/common.py
> +++ b/scripts/qapi/common.py
> @@ -2032,14 +2032,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;
What excactly in your series depends on this?
What safeguards do you propose to ensure an enumeration with
conditionals is compiled only with the exact same conditionals within
the same program?
Example of the kind of deathtrap to guard against: compile
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.
Yes, I know a similar deathtrap will be set up for struct and union
types. No excuse for ignoring either of the two.
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 11/49] qapi/commands: add #if conditions to commands
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 11/49] qapi/commands: add #if conditions to commands Marc-André Lureau
2018-06-21 14:35 ` Markus Armbruster
@ 2018-06-22 8:34 ` Markus Armbruster
2018-06-25 13:15 ` Markus Armbruster
1 sibling, 1 reply; 95+ messages in thread
From: Markus Armbruster @ 2018-06-22 8:34 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, armbru
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Wrap generated code with #if/#endif using an 'ifcontext' on
> QAPIGenCSnippet objects.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi/commands.py | 19 ++++++++++---------
> tests/test-qmp-cmds.c | 4 ++--
> 2 files changed, 12 insertions(+), 11 deletions(-)
>
> diff --git a/scripts/qapi/commands.py b/scripts/qapi/commands.py
> index e2366b4801..40bb680b7c 100644
> --- a/scripts/qapi/commands.py
> +++ b/scripts/qapi/commands.py
> @@ -237,7 +237,7 @@ class QAPISchemaGenCommandVisitor(QAPISchemaModularCVisitor):
> QAPISchemaModularCVisitor.__init__(
> self, prefix, 'qapi-commands',
> ' * Schema-defined QAPI/QMP commands', __doc__)
> - self._regy = ''
> + self._regy = QAPIGenCSnippet()
> self._visited_ret_types = {}
>
> def _begin_module(self, name):
> @@ -273,19 +273,20 @@ class QAPISchemaGenCommandVisitor(QAPISchemaModularCVisitor):
> void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds);
> ''',
> c_prefix=c_name(self._prefix, protect=False)))
> - genc.add(gen_registry(self._regy, self._prefix))
> + genc.add(gen_registry(self._regy.get_content(), self._prefix))
>
> def visit_command(self, name, info, ifcond, arg_type, ret_type,
> gen, success_response, boxed, allow_oob):
> if not gen:
> return
> - self._genh.add(gen_command_decl(name, arg_type, boxed, ret_type))
> - if ret_type and ret_type not in self._visited_ret_types[self._genc]:
> - self._visited_ret_types[self._genc].add(ret_type)
> - self._genc.add(gen_marshal_output(ret_type))
> - self._genh.add(gen_marshal_decl(name))
> - self._genc.add(gen_marshal(name, arg_type, boxed, ret_type))
> - self._regy += gen_register_command(name, success_response, allow_oob)
> + with ifcontext(ifcond, self._genh, self._genc, self._regy):
> + self._genh.add(gen_command_decl(name, arg_type, boxed, ret_type))
> + if ret_type and ret_type not in self._visited_ret_types[self._genc]:
> + self._visited_ret_types[self._genc].add(ret_type)
> + self._genc.add(gen_marshal_output(ret_type))
I'm afraid this falls apart when multiple commands with different
conditions share a return type.
That case needs test coverage.
Aside: the qmp_marshal_FOO() should be static. I can see just two uses
preventing that:
monitor.c:1146: qmp_marshal_qmp_capabilities, QCO_NO_OPTIONS);
monitor.c:4312: qmp_marshal_query_version(NULL, &ver, NULL);
Would be nice to get rid of those. Not necessarily in this series, of
course.
> + self._genh.add(gen_marshal_decl(name))
> + self._genc.add(gen_marshal(name, arg_type, boxed, ret_type))
> + self._regy.add(gen_register_command(name, success_response, allow_oob))
>
>
> def gen_commands(schema, output_dir, prefix):
> diff --git a/tests/test-qmp-cmds.c b/tests/test-qmp-cmds.c
> index c25fc2100a..e675722593 100644
> --- a/tests/test-qmp-cmds.c
> +++ b/tests/test-qmp-cmds.c
> @@ -12,11 +12,11 @@
>
> static QmpCommandList qmp_commands;
>
> -/* #if defined(TEST_IF_STRUCT) && defined(TEST_IF_CMD) */
> +#if defined(TEST_IF_STRUCT) && defined(TEST_IF_CMD)
> void qmp_TestIfCmd(TestIfStruct *foo, Error **errp)
> {
> }
> -/* #endif */
> +#endif
>
> void qmp_user_def_cmd(Error **errp)
> {
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 12/49] qapi/events: add #if conditions to events
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 12/49] qapi/events: add #if conditions to events Marc-André Lureau
2018-06-21 14:40 ` Markus Armbruster
@ 2018-06-22 9:02 ` Markus Armbruster
1 sibling, 0 replies; 95+ messages in thread
From: Markus Armbruster @ 2018-06-22 9:02 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, armbru
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Wrap generated code with #if/#endif using an 'ifcontext' on
> QAPIGenCSnippet objects.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi/events.py | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/scripts/qapi/events.py b/scripts/qapi/events.py
> index 26ae00f6f7..dae03e3d88 100644
> --- a/scripts/qapi/events.py
> +++ b/scripts/qapi/events.py
> @@ -185,8 +185,9 @@ class QAPISchemaGenEventVisitor(QAPISchemaModularCVisitor):
> genc.add(gen_enum_lookup(self._enum_name, self._event_names))
>
> def visit_event(self, name, info, ifcond, arg_type, boxed):
> - self._genh.add(gen_event_send_decl(name, arg_type, boxed))
> - self._genc.add(gen_event_send(name, arg_type, boxed, self._enum_name))
> + with ifcontext(ifcond, self._genh, self._genc):
> + self._genh.add(gen_event_send_decl(name, arg_type, boxed))
> + self._genc.add(gen_event_send(name, arg_type, boxed, self._enum_name))
> self._event_names.append(name)
This makes a conditional event's qapi_event_send_FOO() compile-time
conditional, but its enum QAPIEvent member remains unconditional for
now. I figure it'll get its #if in PATCH 29. Please mention this in
your commit message. You do in PATCH 22.
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code
2018-06-21 17:18 ` Marc-André Lureau
2018-06-22 6:56 ` Markus Armbruster
@ 2018-06-22 9:06 ` Markus Armbruster
1 sibling, 0 replies; 95+ messages in thread
From: Markus Armbruster @ 2018-06-22 9:06 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: Markus Armbruster, QEMU
Marc-André Lureau <marcandre.lureau@gmail.com> writes:
> Hi
>
> On Thu, Jun 21, 2018 at 6:47 PM, Markus Armbruster <armbru@redhat.com> wrote:
>> I think we can bite off a digestible part of this series:
>> target-independent top-level conditionals. I think that's PATCH
>> 01-14,31 and applicable parts of 35-37. The idea is to merge that part
>> quickly, then deal with the (less daunting) remainder. Marc-André, if
>> you agree with that plan, please respin just that part. I can continue
>> review of the remainder without a rebase.
>>
>
> That's ok with me, I'll work on it.
> thanks
Please include the relevant part of PATCH 30 "docs: document schema
configuration". Consider squashing it into PATCH 03.
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 30/49] docs: document schema configuration
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 30/49] docs: document schema configuration Marc-André Lureau
@ 2018-06-22 11:10 ` Markus Armbruster
0 siblings, 0 replies; 95+ messages in thread
From: Markus Armbruster @ 2018-06-22 11:10 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> docs/devel/qapi-code-gen.txt | 38 ++++++++++++++++++++++++++++++++++++
> 1 file changed, 38 insertions(+)
>
> diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt
> index a569d24745..eec52e63e5 100644
> --- a/docs/devel/qapi-code-gen.txt
> +++ b/docs/devel/qapi-code-gen.txt
> @@ -728,6 +728,44 @@ Example: Red Hat, Inc. controls redhat.com, and may therefore add a
> downstream command __com.redhat_drive-mirror.
>
>
> +=== Configuring the schema ===
> +
> +Top-level QAPI expressions and various type expressions listed below
Not sure about "and various type expressions listed below". Perhaps
it's better to start with explaining just top-level conditionals, then
explain member conditionals separately.
> +can take an 'if' key. The value must be a string or a list of
> +string. The corresponding generated code will then guard the inclusion
s/string/strings/
> +of that member in the larger struct or function with #if IFCOND
> +(or several #if lines for a list), where IFCOND is the value of the
> +'if' key.
> +
> +'struct', 'enum', 'union', 'alternate', 'command' and 'event'
> +top-level QAPI expressions can take an 'if' keyword like:
> +
> +{ 'struct': 'IfStruct', 'data': { 'foo': 'int' },
> + 'if': 'defined(IFCOND)' }
> +
> +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.
> +
> +{ 'struct': 'IfStruct', 'data':
> + { 'foo': 'int',
> + 'bar': { 'type': 'int', 'if': 'defined(IFCOND)'} } }
> +
> +An enum value can be replaced by a dictionary with a 'name' and a 'if'
> +key:
> +
> +{ 'enum': 'IfEnum', 'data':
> + [ 'foo',
> + { 'name' : 'bar', 'if': 'defined(IFCOND)' } ] }
> +
> +Please note that you are responsible 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.
> +
> +The presence of 'if' keys in the schema is reflected through to the
> +introspection output depending on the build configuration.
> +
> +
> == Client JSON Protocol introspection ==
>
> Clients of a Client JSON Protocol commonly need to figure out what
Missing: how 'if' affects generated code.
Want me to try my hand at a fixup?
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 17/49] qapi: change enum visitor to take QAPISchemaMember
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 17/49] qapi: change enum visitor to take QAPISchemaMember Marc-André Lureau
@ 2018-06-22 12:24 ` Markus Armbruster
0 siblings, 0 replies; 95+ messages in thread
From: Markus Armbruster @ 2018-06-22 12:24 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, armbru
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/common.py | 12 ++++++------
> scripts/qapi/events.py | 2 +-
> scripts/qapi/introspect.py | 3 ++-
> tests/qapi-schema/test-qapi.py | 2 +-
> 4 files changed, 10 insertions(+), 9 deletions(-)
>
> diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
> index ea5cdfe3be..4d19146064 100644
> --- a/scripts/qapi/common.py
> +++ b/scripts/qapi/common.py
> @@ -1198,7 +1198,7 @@ class QAPISchemaEnumType(QAPISchemaType):
>
> 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):
> @@ -2007,11 +2007,11 @@ const QEnumLookup %(c_name)s_lookup = {
> ''',
> c_name=c_name(name))
> for m in members:
> - index = c_enum_const(name, m, prefix)
> + index = c_enum_const(name, m.name, prefix)
> ret += mcgen('''
> - [%(index)s] = "%(value)s",
> + [%(index)s] = "%(name)s",
> ''',
> - index=index, value=m)
> + index=index, name=m.name)
>
> ret += mcgen('''
> },
> @@ -2024,7 +2024,7 @@ const QEnumLookup %(c_name)s_lookup = {
>
> def gen_enum(name, members, prefix=None):
> # append automatically generated _MAX value
> - enum_members = members + ['_MAX']
> + enum_members = members + [QAPISchemaMember('_MAX')]
>
> ret = mcgen('''
>
This hunk gave me pause...
> @@ -2036,7 +2036,7 @@ typedef enum %(c_name)s {
> ret += mcgen('''
> %(c_enum)s,
> ''',
> - c_enum=c_enum_const(name, m, prefix))
> + c_enum=c_enum_const(name, m.name, prefix))
>
> ret += mcgen('''
> } %(c_name)s;
> diff --git a/scripts/qapi/events.py b/scripts/qapi/events.py
> index dae03e3d88..233c27a6c8 100644
> --- a/scripts/qapi/events.py
> +++ b/scripts/qapi/events.py
> @@ -188,7 +188,7 @@ class QAPISchemaGenEventVisitor(QAPISchemaModularCVisitor):
> with ifcontext(ifcond, self._genh, self._genc):
> self._genh.add(gen_event_send_decl(name, arg_type, boxed))
> self._genc.add(gen_event_send(name, arg_type, boxed, self._enum_name))
> - self._event_names.append(name)
> + self._event_names.append(QAPISchemaMember(name))
>
>
... and this one as well, until I realized that you're *also* changing
gen_enum_lookup() and gen_enum(). And then I realized that I missed
something about the previous patch. Going to explain it there.
Anyway, let's mention the change to gen_enum_lookup() and gen_enum() in
the commit message.
> def gen_events(schema, output_dir, prefix):
> diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
> index 66f7fd00a9..d62fca84de 100644
> --- a/scripts/qapi/introspect.py
> +++ b/scripts/qapi/introspect.py
> @@ -164,7 +164,8 @@ const QLitObject %(c_name)s = %(c_string)s;
> self._gen_qlit(name, 'builtin', {'json-type': json_type}, [])
>
> def visit_enum_type(self, name, info, ifcond, members, prefix):
> - self._gen_qlit(name, 'enum', {'values': members}, ifcond)
> + 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/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
> index f4b8feb9bc..3623deae62 100644
> --- a/tests/qapi-schema/test-qapi.py
> +++ b/tests/qapi-schema/test-qapi.py
> @@ -24,7 +24,7 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
> print('include %s' % name)
>
> def visit_enum_type(self, name, info, ifcond, members, prefix):
> - print('enum %s %s' % (name, members))
> + print('enum %s %s' % (name, [m.name for m in members]))
> if prefix:
> print(' prefix %s' % prefix)
> self._print_if(ifcond)
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 16/49] qapi: rename QAPISchemaEnumType.values to .members
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 16/49] qapi: rename QAPISchemaEnumType.values to .members Marc-André Lureau
@ 2018-06-22 12:24 ` Markus Armbruster
0 siblings, 0 replies; 95+ messages in thread
From: Markus Armbruster @ 2018-06-22 12:24 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, armbru
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> 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.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
I agree with renaming @values to @members where it's a list of
QAPISchemaMembers.
> ---
> scripts/qapi/common.py | 36 +++++++++++++++++-----------------
> scripts/qapi/doc.py | 2 +-
> scripts/qapi/introspect.py | 4 ++--
> scripts/qapi/types.py | 6 +++---
> scripts/qapi/visit.py | 2 +-
> tests/qapi-schema/test-qapi.py | 4 ++--
> 6 files changed, 27 insertions(+), 27 deletions(-)
>
> diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
> index 68a567f53f..ea5cdfe3be 100644
> --- a/scripts/qapi/common.py
> +++ b/scripts/qapi/common.py
> @@ -1068,7 +1068,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):
This one is still a list of strings. The next patch changes it to list
of QAPISchemaMembers, and that's when it should be renamed.
> pass
>
> def visit_array_type(self, name, info, ifcond, element_type):
> @@ -1166,22 +1166,22 @@ 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):
> QAPISchemaType.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()
> @@ -1191,7 +1191,7 @@ 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'
> @@ -1999,19 +1999,19 @@ def wrap_ifcond(ifcond, before, after):
> return out
>
>
> -def gen_enum_lookup(name, values, prefix=None):
> +def gen_enum_lookup(name, members, prefix=None):
Likewise.
> 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, prefix)
> ret += mcgen('''
> [%(index)s] = "%(value)s",
> ''',
> - index=index, value=value)
> + index=index, value=m)
>
> ret += mcgen('''
> },
> @@ -2022,9 +2022,9 @@ const QEnumLookup %(c_name)s_lookup = {
> return ret
>
>
> -def gen_enum(name, values, prefix=None):
> +def gen_enum(name, members, prefix=None):
Likewise.
> # append automatically generated _MAX value
> - enum_values = values + ['_MAX']
> + enum_members = members + ['_MAX']
>
> ret = mcgen('''
>
> @@ -2032,11 +2032,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, prefix))
>
> ret += mcgen('''
> } %(c_name)s;
> diff --git a/scripts/qapi/doc.py b/scripts/qapi/doc.py
> index d5cfd2336b..6c2bf98e1d 100755
> --- a/scripts/qapi/doc.py
> +++ b/scripts/qapi/doc.py
> @@ -204,7 +204,7 @@ class QAPISchemaGenDocVisitor(qapi.common.QAPISchemaVisitor):
> def write(self, output_dir):
> self._gen.write(output_dir, self._prefix + 'qapi-doc.texi')
>
> - def visit_enum_type(self, name, info, ifcond, values, prefix):
> + def visit_enum_type(self, name, info, ifcond, members, prefix):
> doc = self.cur_doc
> self._gen.add(TYPE_FMT(type='Enum',
> name=doc.symbol,
Likewise. More of the same below.
> diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
> index cb4825f134..66f7fd00a9 100644
> --- a/scripts/qapi/introspect.py
> +++ b/scripts/qapi/introspect.py
> @@ -163,8 +163,8 @@ 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, 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': 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 ce4c91206c..5b790cb41d 100644
> --- a/scripts/qapi/types.py
> +++ b/scripts/qapi/types.py
> @@ -213,10 +213,10 @@ class QAPISchemaGenTypeVisitor(QAPISchemaModularCVisitor):
> self._genh.add(gen_type_cleanup_decl(name))
> self._genc.add(gen_type_cleanup(name))
>
> - def visit_enum_type(self, name, info, ifcond, values, prefix):
> + def visit_enum_type(self, name, info, ifcond, members, prefix):
> with ifcontext(ifcond, self._genh, self._genc):
> - self._genh.preamble_add(gen_enum(name, values, prefix))
> - self._genc.add(gen_enum_lookup(name, values, prefix))
> + self._genh.preamble_add(gen_enum(name, members, prefix))
> + self._genc.add(gen_enum_lookup(name, members, prefix))
>
> def visit_array_type(self, name, info, ifcond, element_type):
> with ifcontext(ifcond, self._genh):
> diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py
> index e4a62ce030..ee776386ae 100644
> --- a/scripts/qapi/visit.py
> +++ b/scripts/qapi/visit.py
> @@ -301,7 +301,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor):
> ''',
> types=types))
>
> - def visit_enum_type(self, name, info, ifcond, values, prefix):
> + def visit_enum_type(self, name, info, ifcond, members, prefix):
> with ifcontext(ifcond, self._genh, self._genc):
> self._genh.add(gen_visit_decl(name, scalar=True))
> self._genc.add(gen_visit_enum(name))
> diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
> index 6d25a37dda..f4b8feb9bc 100644
> --- a/tests/qapi-schema/test-qapi.py
> +++ b/tests/qapi-schema/test-qapi.py
> @@ -23,8 +23,8 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
> def visit_include(self, name, info):
> print('include %s' % name)
>
> - 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 %s' % (name, members))
> if prefix:
> print(' prefix %s' % prefix)
> self._print_if(ifcond)
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 18/49] tests: modify visit_enum_type() in test-qapi to print members
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 18/49] tests: modify visit_enum_type() in test-qapi to print members Marc-André Lureau
@ 2018-06-22 14:10 ` Markus Armbruster
0 siblings, 0 replies; 95+ messages in thread
From: Markus Armbruster @ 2018-06-22 14:10 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, armbru
The subject is misleading: visit_enum_type() prints members even before
this patch already.
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> Use a common self._print_members() to print enum members details.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> tests/qapi-schema/comments.out | 14 ++++++-
> tests/qapi-schema/doc-bad-section.out | 13 ++++++-
> 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 | 18 ++++++---
> 12 files changed, 158 insertions(+), 31 deletions(-)
>
> diff --git a/tests/qapi-schema/comments.out b/tests/qapi-schema/comments.out
> index 8d2f1ce8a2..d1abc4b5a1 100644
> --- a/tests/qapi-schema/comments.out
> +++ b/tests/qapi-schema/comments.out
> @@ -1,5 +1,15 @@
> object q_empty
> -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
> module comments.json
> -enum Status ['good', 'bad', 'ugly']
> +enum Status
> + member good
> + member bad
> + member ugly
[More of the same...]
> diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
> index 3623deae62..7e7b8f9f0f 100644
> --- a/tests/qapi-schema/test-qapi.py
> +++ b/tests/qapi-schema/test-qapi.py
> @@ -12,7 +12,8 @@
>
> from __future__ import print_function
> import sys
> -from qapi.common import QAPIError, QAPISchema, QAPISchemaVisitor
> +from qapi.common import QAPIError, QAPISchema, QAPISchemaVisitor, \
> + QAPISchemaObjectTypeMember
>
>
> class QAPISchemaTestVisitor(QAPISchemaVisitor):
> @@ -24,18 +25,17 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
> print('include %s' % name)
>
> def visit_enum_type(self, name, info, ifcond, members, prefix):
> - print('enum %s %s' % (name, [m.name for m in members]))
> + 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)
>
> @@ -57,6 +57,14 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
> print(' boxed=%s' % boxed)
> self._print_if(ifcond)
>
> + @staticmethod
> + def _print_members(members):
> + for m in members:
> + print(' member %s%s' % (
> + m.name,
> + ': %s optional=%s' % (m.type.name, m.optional)
> + if isinstance(m, QAPISchemaObjectTypeMember) else ''))
> +
> @staticmethod
> def _print_variants(variants):
> if variants:
I don't think the de-duplication is worth the isinstance() ugliness,
even with PATCH 21's additional line.
Compare the stupidest possible solution:
diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
index 3623deae62..37547dc233 100644
--- a/tests/qapi-schema/test-qapi.py
+++ b/tests/qapi-schema/test-qapi.py
@@ -24,9 +24,11 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
print('include %s' % name)
def visit_enum_type(self, name, info, ifcond, members, prefix):
- print('enum %s %s' % (name, [m.name for m in members]))
+ print('enum %s' % name)
if prefix:
print(' prefix %s' % prefix)
+ for m in members:
+ print(' member %s' % m.name)
self._print_if(ifcond)
def visit_object_type(self, name, info, ifcond, base, members, variants):
PATCH 21 will then add two lines instead of one. Still less code, and
simpler, too.
Revised commit message could be:
tests: Print enum type members more like object type members
Commit 93bda4dd461 changed the internal representation of enum type
members from str to QAPISchemaMember, but we still print only a
string. Has been good enough, as the name is the member's only
attribute of interest, but that's about to change. To prepare,
print them more like object type members.
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 11/49] qapi/commands: add #if conditions to commands
2018-06-22 8:34 ` Markus Armbruster
@ 2018-06-25 13:15 ` Markus Armbruster
0 siblings, 0 replies; 95+ messages in thread
From: Markus Armbruster @ 2018-06-25 13:15 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel
Markus Armbruster <armbru@redhat.com> writes:
> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>
>> Wrap generated code with #if/#endif using an 'ifcontext' on
>> QAPIGenCSnippet objects.
>>
>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>> ---
>> scripts/qapi/commands.py | 19 ++++++++++---------
>> tests/test-qmp-cmds.c | 4 ++--
>> 2 files changed, 12 insertions(+), 11 deletions(-)
>>
>> diff --git a/scripts/qapi/commands.py b/scripts/qapi/commands.py
>> index e2366b4801..40bb680b7c 100644
>> --- a/scripts/qapi/commands.py
>> +++ b/scripts/qapi/commands.py
>> @@ -237,7 +237,7 @@ class QAPISchemaGenCommandVisitor(QAPISchemaModularCVisitor):
>> QAPISchemaModularCVisitor.__init__(
>> self, prefix, 'qapi-commands',
>> ' * Schema-defined QAPI/QMP commands', __doc__)
>> - self._regy = ''
>> + self._regy = QAPIGenCSnippet()
>> self._visited_ret_types = {}
>>
>> def _begin_module(self, name):
>> @@ -273,19 +273,20 @@ class QAPISchemaGenCommandVisitor(QAPISchemaModularCVisitor):
>> void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds);
>> ''',
>> c_prefix=c_name(self._prefix, protect=False)))
>> - genc.add(gen_registry(self._regy, self._prefix))
>> + genc.add(gen_registry(self._regy.get_content(), self._prefix))
>>
>> def visit_command(self, name, info, ifcond, arg_type, ret_type,
>> gen, success_response, boxed, allow_oob):
>> if not gen:
>> return
>> - self._genh.add(gen_command_decl(name, arg_type, boxed, ret_type))
>> - if ret_type and ret_type not in self._visited_ret_types[self._genc]:
>> - self._visited_ret_types[self._genc].add(ret_type)
>> - self._genc.add(gen_marshal_output(ret_type))
>> - self._genh.add(gen_marshal_decl(name))
>> - self._genc.add(gen_marshal(name, arg_type, boxed, ret_type))
>> - self._regy += gen_register_command(name, success_response, allow_oob)
>> + with ifcontext(ifcond, self._genh, self._genc, self._regy):
>> + self._genh.add(gen_command_decl(name, arg_type, boxed, ret_type))
>> + if ret_type and ret_type not in self._visited_ret_types[self._genc]:
>> + self._visited_ret_types[self._genc].add(ret_type)
>> + self._genc.add(gen_marshal_output(ret_type))
>
> I'm afraid this falls apart when multiple commands with different
> conditions share a return type.
If you'd rather fix this later, we can consider just documenting the bug
for now.
> That case needs test coverage.
Needed regardless.
[...]
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 19/49] qapi: factor out check_known_keys()
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 19/49] qapi: factor out check_known_keys() Marc-André Lureau
@ 2018-06-25 14:10 ` Markus Armbruster
0 siblings, 0 replies; 95+ messages in thread
From: Markus Armbruster @ 2018-06-25 14:10 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, armbru
Marc-André Lureau <marcandre.lureau@redhat.com> writes:
> The following patches are going to need similar checks from various
> code path. This refactoring will report all conflicting keys (instead
> of the first one encountered).
>
> Modify unknown-expr-key to check plural form.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi/common.py | 27 ++++++++++++++++++-------
> tests/qapi-schema/alternate-base.err | 2 +-
> tests/qapi-schema/double-type.err | 2 +-
> tests/qapi-schema/enum-missing-data.err | 2 +-
> tests/qapi-schema/unknown-expr-key.err | 2 +-
> tests/qapi-schema/unknown-expr-key.json | 2 +-
> 6 files changed, 25 insertions(+), 12 deletions(-)
>
> diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
> index 4d19146064..fdbb5f1823 100644
> --- a/scripts/qapi/common.py
> +++ b/scripts/qapi/common.py
> @@ -879,6 +879,24 @@ def check_struct(expr, info):
> allow_metas=['struct'])
>
>
> +def check_known_keys(info, source, keys, required, optional):
> +
> + def pprint(elems):
> + return ', '.join("'" + e + "'" for e in sorted(elems))
> +
> + missing = set(required) - set(keys)
> + if missing:
> + raise QAPISemError(info, "%s must have %s key%s"
> + % (source, pprint(missing),
> + 's' if len(missing) > 1 else ''))
> + allowed = set(required + optional)
> + unknown = set(keys) - allowed
> + if unknown:
> + raise QAPISemError(info, "%s has unknown key%s %s (allowed: %s)"
> + % (source, 's' if len(unknown) > 1 else '',
> + pprint(unknown), pprint(allowed)))
> +
> +
> def check_keys(expr_elem, meta, required, optional=[]):
> expr = expr_elem['expr']
> info = expr_elem['info']
> @@ -886,10 +904,9 @@ def check_keys(expr_elem, meta, required, optional=[]):
> if not isinstance(name, str):
> raise QAPISemError(info, "'%s' key must have a string value" % meta)
> required = required + [meta]
> + source = "%s '%s'" % (meta, name)
> + check_known_keys(info, source, expr, required, optional)
> for (key, value) in expr.items():
> - if key not in required and key not in optional:
> - raise QAPISemError(info, "Unknown key '%s' in %s '%s'"
> - % (key, meta, name))
> if (key == 'gen' or key == 'success-response') and value is not False:
> raise QAPISemError(info,
> "'%s' of %s '%s' should only use false value"
> @@ -900,10 +917,6 @@ def check_keys(expr_elem, meta, required, optional=[]):
> % (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'"
> - % (key, meta, name))
>
>
> def check_exprs(exprs):
> diff --git a/tests/qapi-schema/alternate-base.err b/tests/qapi-schema/alternate-base.err
> index 30d8a34373..2b09c4c7a3 100644
> --- a/tests/qapi-schema/alternate-base.err
> +++ b/tests/qapi-schema/alternate-base.err
> @@ -1 +1 @@
> -tests/qapi-schema/alternate-base.json:4: Unknown key 'base' in alternate 'Alt'
> +tests/qapi-schema/alternate-base.json:4: alternate 'Alt' has unknown key 'base' (allowed: 'alternate', 'data', 'if')
The change in the error message proper, i.e. up to the parenthesis,
doesn't feel like an improvment to me. The old message starts with
what's wrong. The new one starts with where's something wrong.
I'd do the parenthesis with error_append_hint(), and say something like
"Valid keys are ...". See below for a more complete example.
> diff --git a/tests/qapi-schema/double-type.err b/tests/qapi-schema/double-type.err
> index f9613c6d6b..a8c5637659 100644
> --- a/tests/qapi-schema/double-type.err
> +++ b/tests/qapi-schema/double-type.err
> @@ -1 +1 @@
> -tests/qapi-schema/double-type.json:2: Unknown key 'command' in struct 'bar'
> +tests/qapi-schema/double-type.json:2: struct 'bar' has unknown key 'command' (allowed: 'base', 'data', 'if', 'struct')
> diff --git a/tests/qapi-schema/enum-missing-data.err b/tests/qapi-schema/enum-missing-data.err
> index ba4873ae69..68e286badc 100644
> --- a/tests/qapi-schema/enum-missing-data.err
> +++ b/tests/qapi-schema/enum-missing-data.err
> @@ -1 +1 @@
> -tests/qapi-schema/enum-missing-data.json:2: Key 'data' is missing from enum 'MyEnum'
> +tests/qapi-schema/enum-missing-data.json:2: enum 'MyEnum' must have 'data' key
Again, the error message change doesn't feel like an improvement to me.
> diff --git a/tests/qapi-schema/unknown-expr-key.err b/tests/qapi-schema/unknown-expr-key.err
> index 12f5ed5b43..d9f4e41cac 100644
> --- a/tests/qapi-schema/unknown-expr-key.err
> +++ b/tests/qapi-schema/unknown-expr-key.err
> @@ -1 +1 @@
> -tests/qapi-schema/unknown-expr-key.json:2: Unknown key 'bogus' in struct 'bar'
> +tests/qapi-schema/unknown-expr-key.json:2: struct 'bar' has unknown keys 'bogus', 'foo' (allowed: 'base', 'data', 'if', 'struct')
> diff --git a/tests/qapi-schema/unknown-expr-key.json b/tests/qapi-schema/unknown-expr-key.json
Suggest something like
tests/qapi-schema/unknown-expr-key.json:2: Unknown keys 'bogus', 'foo' in struct 'bar'
Valid keys are 'base', 'data', 'if', 'struct'.
> index 3b2be00cc4..5bcb8efd1d 100644
> --- a/tests/qapi-schema/unknown-expr-key.json
> +++ b/tests/qapi-schema/unknown-expr-key.json
> @@ -1,2 +1,2 @@
> # we reject an expression with unknown top-level keys
> -{ 'struct': 'bar', 'data': { 'string': 'str'}, 'bogus': { } }
> +{ 'struct': 'bar', 'data': { 'string': 'str'}, 'bogus': { }, 'foo': { } }
The patch does two things: 1. factor out a helper for later use in other
places, 2. report all offending keys instead of just the first one.
Split it up, please.
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 05/49] qapi: leave the ifcond attribute undefined until check()
2018-06-19 9:06 ` Markus Armbruster
@ 2018-06-26 13:39 ` Marc-André Lureau
2018-06-27 5:26 ` Markus Armbruster
0 siblings, 1 reply; 95+ messages in thread
From: Marc-André Lureau @ 2018-06-26 13:39 UTC (permalink / raw)
To: Markus Armbruster; +Cc: QEMU
Hi
On Tue, Jun 19, 2018 at 11:06 AM, Markus Armbruster <armbru@redhat.com> wrote:
> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>
>> 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.
>>
>> Leave the ifcond attribute undefined until check().
>
> Drawback: pylint complains. We'll live.
>
>>
>> Suggested-by: Markus Armbruster <armbru@redhat.com>
>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>> Reviewed-by: Markus Armbruster <armbru@redhat.com>
>
> Shouldn't this be squashed into the previous patch?
I would rather keep it seperate, as it makes reviewing both a bit
easier to me. But feel free to squash on commit.
>
>> ---
>> scripts/qapi/common.py | 21 +++++++++++++++++----
>> 1 file changed, 17 insertions(+), 4 deletions(-)
>>
>> diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
>> index d8ab3d8f7f..eb07d641ab 100644
>> --- a/scripts/qapi/common.py
>> +++ b/scripts/qapi/common.py
>> @@ -1026,13 +1026,19 @@ class QAPISchemaEntity(object):
>> # such place).
>> self.info = info
>> self.doc = doc
>> - self.ifcond = listify_cond(ifcond)
>> + self._ifcond = ifcond # self.ifcond is set only after .check()
>>
>> def c_name(self):
>> return c_name(self.name)
>>
>> def check(self, schema):
>> - pass
>> + if isinstance(self._ifcond, QAPISchemaType):
>> + # inherit the condition from a type
>> + typ = self._ifcond
>> + typ.check(schema)
>> + self.ifcond = typ.ifcond
>> + else:
>> + self.ifcond = listify_cond(self._ifcond)
>
> Whenever we add a .check(), we need to prove QAPISchema.check()'s
> recursion still terminates, and terminates the right way.
>
> Argument before this patch: we recurse only into types contained in
> types, e.g. an object type's base type, and we detect and report cycles
> as "Object %s contains itself", in QAPISchemaObjectType.check().
>
> The .check() added here recurses into a type. If this creates a cycle,
> it'll be caught and reported as "contains itself". We still need to
> show that the error message remains accurate.
>
> We .check() here to inherit .ifcond from a type. As far as I can tell,
> we use this inheritance feature only to inherit an array's condition
> from its element type. That's safe, because an array does contain its
> elements.
>
> This is hardly a rigorous proof. Just enough to make me believe your
> code works.
>
> However, I suspect adding the inheritance feature at the entity level
> complicates the correctness argument without real need. Can we restrict
> it to array elements? Have QAPISchemaArrayType.check() resolve
> type-valued ._ifcond, and all the others choke on it?
There is also implicit object types.
>
>>
>> def is_implicit(self):
>> return not self.info
>> @@ -1169,6 +1175,7 @@ class QAPISchemaEnumType(QAPISchemaType):
>> self.prefix = prefix
>>
>> def check(self, schema):
>> + QAPISchemaType.check(self, schema)
>> seen = {}
>> for v in self.values:
>> v.check_clash(self.info, seen)
>> @@ -1201,8 +1208,10 @@ class QAPISchemaArrayType(QAPISchemaType):
>> self.element_type = None
>>
>> def check(self, schema):
>> + QAPISchemaType.check(self, schema)
>> self.element_type = schema.lookup_type(self._element_type_name)
>> assert self.element_type
>> + self.element_type.check(schema)
>> self.ifcond = self.element_type.ifcond
>>
>> def is_implicit(self):
>> @@ -1245,6 +1254,7 @@ class QAPISchemaObjectType(QAPISchemaType):
>> self.members = None
>>
>> def check(self, schema):
>> + QAPISchemaType.check(self, schema)
>> if self.members is False: # check for cycles
>> raise QAPISemError(self.info,
>> "Object %s contains itself" % self.name)
>> @@ -1427,6 +1437,7 @@ class QAPISchemaAlternateType(QAPISchemaType):
>> self.variants = variants
>>
>> def check(self, schema):
>> + QAPISchemaType.check(self, schema)
>> self.variants.tag_member.check(schema)
>> # Not calling self.variants.check_clash(), because there's nothing
>> # to clash with
>> @@ -1470,6 +1481,7 @@ class QAPISchemaCommand(QAPISchemaEntity):
>> self.allow_oob = allow_oob
>>
>> def check(self, schema):
>> + QAPISchemaEntity.check(self, schema)
>> if self._arg_type_name:
>> self.arg_type = schema.lookup_type(self._arg_type_name)
>> assert (isinstance(self.arg_type, QAPISchemaObjectType) or
>> @@ -1504,6 +1516,7 @@ class QAPISchemaEvent(QAPISchemaEntity):
>> self.boxed = boxed
>>
>> def check(self, schema):
>> + QAPISchemaEntity.check(self, schema)
>> if self._arg_type_name:
>> self.arg_type = schema.lookup_type(self._arg_type_name)
>> assert (isinstance(self.arg_type, QAPISchemaObjectType) or
>> @@ -1633,7 +1646,7 @@ class QAPISchema(object):
>> # 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
>> + assert ifcond == typ._ifcond
>
> pylint complains
>
> W:1649,29: Access to a protected member _ifcond of a client class (protected-access)
>
> Layering violation. Tolerable, I think.
>
yeah, alternative would be to add an assert_ifcond() method in type..?
I'll add a # pylint: disable=protected-access for now
>> self._def_entity(QAPISchemaObjectType(name, info, doc, ifcond,
>> None, members, None))
>> @@ -1679,7 +1692,7 @@ class QAPISchema(object):
>> 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,
>> + typ, info, None, self.lookup_type(typ),
>> 'wrapper', [self._make_member('data', typ, info)])
>> return QAPISchemaObjectTypeVariant(case, typ)
>
> Perhaps other attributes that become valid only at .check() time should
> receive the same treatment. Not necessarily in this series, not
> necessarily by you. A TODO comment wouldn't hurt, though.
>
It doesn't look obvious to me which should receive the same
treatement. I'll leave that to you to figure out :)
--
Marc-André Lureau
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 05/49] qapi: leave the ifcond attribute undefined until check()
2018-06-26 13:39 ` Marc-André Lureau
@ 2018-06-27 5:26 ` Markus Armbruster
2018-06-29 10:30 ` Marc-André Lureau
0 siblings, 1 reply; 95+ messages in thread
From: Markus Armbruster @ 2018-06-27 5:26 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: Markus Armbruster, QEMU
Marc-André Lureau <marcandre.lureau@gmail.com> writes:
> Hi
>
> On Tue, Jun 19, 2018 at 11:06 AM, Markus Armbruster <armbru@redhat.com> wrote:
>> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>>
>>> 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.
>>>
>>> Leave the ifcond attribute undefined until check().
>>
>> Drawback: pylint complains. We'll live.
>>
>>>
>>> Suggested-by: Markus Armbruster <armbru@redhat.com>
>>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>>> Reviewed-by: Markus Armbruster <armbru@redhat.com>
>>
>> Shouldn't this be squashed into the previous patch?
>
> I would rather keep it seperate, as it makes reviewing both a bit
> easier to me. But feel free to squash on commit.
No need to decide right now.
>>
>>> ---
>>> scripts/qapi/common.py | 21 +++++++++++++++++----
>>> 1 file changed, 17 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
>>> index d8ab3d8f7f..eb07d641ab 100644
>>> --- a/scripts/qapi/common.py
>>> +++ b/scripts/qapi/common.py
>>> @@ -1026,13 +1026,19 @@ class QAPISchemaEntity(object):
>>> # such place).
>>> self.info = info
>>> self.doc = doc
>>> - self.ifcond = listify_cond(ifcond)
>>> + self._ifcond = ifcond # self.ifcond is set only after .check()
>>>
>>> def c_name(self):
>>> return c_name(self.name)
>>>
>>> def check(self, schema):
>>> - pass
>>> + if isinstance(self._ifcond, QAPISchemaType):
>>> + # inherit the condition from a type
>>> + typ = self._ifcond
>>> + typ.check(schema)
>>> + self.ifcond = typ.ifcond
>>> + else:
>>> + self.ifcond = listify_cond(self._ifcond)
>>
>> Whenever we add a .check(), we need to prove QAPISchema.check()'s
>> recursion still terminates, and terminates the right way.
>>
>> Argument before this patch: we recurse only into types contained in
>> types, e.g. an object type's base type, and we detect and report cycles
>> as "Object %s contains itself", in QAPISchemaObjectType.check().
>>
>> The .check() added here recurses into a type. If this creates a cycle,
>> it'll be caught and reported as "contains itself". We still need to
>> show that the error message remains accurate.
>>
>> We .check() here to inherit .ifcond from a type. As far as I can tell,
>> we use this inheritance feature only to inherit an array's condition
>> from its element type. That's safe, because an array does contain its
>> elements.
>>
>> This is hardly a rigorous proof. Just enough to make me believe your
>> code works.
>>
>> However, I suspect adding the inheritance feature at the entity level
>> complicates the correctness argument without real need. Can we restrict
>> it to array elements? Have QAPISchemaArrayType.check() resolve
>> type-valued ._ifcond, and all the others choke on it?
>
> There is also implicit object types.
Can you give an example?
>>>
>>> def is_implicit(self):
>>> return not self.info
>>> @@ -1169,6 +1175,7 @@ class QAPISchemaEnumType(QAPISchemaType):
>>> self.prefix = prefix
>>>
>>> def check(self, schema):
>>> + QAPISchemaType.check(self, schema)
>>> seen = {}
>>> for v in self.values:
>>> v.check_clash(self.info, seen)
>>> @@ -1201,8 +1208,10 @@ class QAPISchemaArrayType(QAPISchemaType):
>>> self.element_type = None
>>>
>>> def check(self, schema):
>>> + QAPISchemaType.check(self, schema)
>>> self.element_type = schema.lookup_type(self._element_type_name)
>>> assert self.element_type
>>> + self.element_type.check(schema)
>>> self.ifcond = self.element_type.ifcond
>>>
>>> def is_implicit(self):
>>> @@ -1245,6 +1254,7 @@ class QAPISchemaObjectType(QAPISchemaType):
>>> self.members = None
>>>
>>> def check(self, schema):
>>> + QAPISchemaType.check(self, schema)
>>> if self.members is False: # check for cycles
>>> raise QAPISemError(self.info,
>>> "Object %s contains itself" % self.name)
>>> @@ -1427,6 +1437,7 @@ class QAPISchemaAlternateType(QAPISchemaType):
>>> self.variants = variants
>>>
>>> def check(self, schema):
>>> + QAPISchemaType.check(self, schema)
>>> self.variants.tag_member.check(schema)
>>> # Not calling self.variants.check_clash(), because there's nothing
>>> # to clash with
>>> @@ -1470,6 +1481,7 @@ class QAPISchemaCommand(QAPISchemaEntity):
>>> self.allow_oob = allow_oob
>>>
>>> def check(self, schema):
>>> + QAPISchemaEntity.check(self, schema)
>>> if self._arg_type_name:
>>> self.arg_type = schema.lookup_type(self._arg_type_name)
>>> assert (isinstance(self.arg_type, QAPISchemaObjectType) or
>>> @@ -1504,6 +1516,7 @@ class QAPISchemaEvent(QAPISchemaEntity):
>>> self.boxed = boxed
>>>
>>> def check(self, schema):
>>> + QAPISchemaEntity.check(self, schema)
>>> if self._arg_type_name:
>>> self.arg_type = schema.lookup_type(self._arg_type_name)
>>> assert (isinstance(self.arg_type, QAPISchemaObjectType) or
>>> @@ -1633,7 +1646,7 @@ class QAPISchema(object):
>>> # 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
>>> + assert ifcond == typ._ifcond
>>
>> pylint complains
>>
>> W:1649,29: Access to a protected member _ifcond of a client class (protected-access)
>>
>> Layering violation. Tolerable, I think.
>>
>
> yeah, alternative would be to add an assert_ifcond() method in type..?
> I'll add a # pylint: disable=protected-access for now
Wortwhile only if we make an effort to clean up or suppress the other
pylint gripes. I'll look into it. Go ahead and add the directive
meanwhile; easily dropped it if we decide we don't want it.
>>> self._def_entity(QAPISchemaObjectType(name, info, doc, ifcond,
>>> None, members, None))
>>> @@ -1679,7 +1692,7 @@ class QAPISchema(object):
>>> 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,
>>> + typ, info, None, self.lookup_type(typ),
>>> 'wrapper', [self._make_member('data', typ, info)])
>>> return QAPISchemaObjectTypeVariant(case, typ)
>>
>> Perhaps other attributes that become valid only at .check() time should
>> receive the same treatment. Not necessarily in this series, not
>> necessarily by you. A TODO comment wouldn't hurt, though.
>>
>
> It doesn't look obvious to me which should receive the same
> treatement. I'll leave that to you to figure out :)
Fair enough.
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 14/49] qapi-types: add #if conditions to types & visitors
2018-06-21 16:12 ` Markus Armbruster
@ 2018-06-27 11:59 ` Marc-André Lureau
2018-06-28 6:27 ` Markus Armbruster
0 siblings, 1 reply; 95+ messages in thread
From: Marc-André Lureau @ 2018-06-27 11:59 UTC (permalink / raw)
To: Markus Armbruster; +Cc: QEMU
Hi
On Thu, Jun 21, 2018 at 6:12 PM, Markus Armbruster <armbru@redhat.com> wrote:
> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>
>> Types & visitors are coupled and must be handled together to avoid
>> temporary build regression.
>>
>> Wrap generated types/visitor code with #if/#endif using the context
>> helpers.
>>
>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>> ---
>> scripts/qapi/types.py | 46 ++++++++++++++++++++++++++-----------------
>> scripts/qapi/visit.py | 33 ++++++++++++++++++-------------
>> 2 files changed, 47 insertions(+), 32 deletions(-)
>>
>> diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py
>> index 3d9b0f9a07..ce4c91206c 100644
>> --- a/scripts/qapi/types.py
>> +++ b/scripts/qapi/types.py
>> @@ -61,8 +61,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)
>
> Ignorant question out of curiosity, why is with ifcontext() not usable
> here?
>
ifcontext() works on QAPIGen objects. We could make it work on strings
too, but I don't think it's necessary.
>> return ret
>>
>>
>> @@ -206,41 +208,49 @@ class QAPISchemaGenTypeVisitor(QAPISchemaModularCVisitor):
>> # gen_object() is recursive, ensure it doesn't visit the empty type
>> objects_seen.add(schema.the_empty_object_type.name)
>>
>> - def _gen_type_cleanup(self, name):
>> - self._genh.add(gen_type_cleanup_decl(name))
>> - self._genc.add(gen_type_cleanup(name))
>> + def _gen_type_cleanup(self, name, ifcond):
>> + with ifcontext(ifcond, self._genh, self._genc):
>> + self._genh.add(gen_type_cleanup_decl(name))
>> + self._genc.add(gen_type_cleanup(name))
>>
>> def visit_enum_type(self, name, info, ifcond, values, prefix):
>> - self._genh.preamble_add(gen_enum(name, values, prefix))
>> - self._genc.add(gen_enum_lookup(name, values, prefix))
>> + with ifcontext(ifcond, self._genh, self._genc):
>> + self._genh.preamble_add(gen_enum(name, values, prefix))
>> + self._genc.add(gen_enum_lookup(name, values, prefix))
>>
>> def visit_array_type(self, name, info, ifcond, element_type):
>> - self._genh.preamble_add(gen_fwd_object_or_array(name))
>> - self._genh.add(gen_array(name, element_type))
>> - self._gen_type_cleanup(name)
>> + with ifcontext(ifcond, self._genh):
>> + self._genh.preamble_add(gen_fwd_object_or_array(name))
>> + self._genh.add(gen_array(name, element_type))
>> + self._gen_type_cleanup(name, ifcond)
>>
>> def _gen_object(self, name, info, ifcond, base, members, variants):
>> - self._genh.add(gen_object(name, base, members, variants))
>> - if base and not base.is_implicit():
>> - self._genh.add(gen_upcast(name, base))
>> - # TODO Worth changing the visitor signature, so we could
>> - # directly use rather than repeat type.is_implicit()?
>> + with ifcontext(ifcond, self._genh):
>> + self._genh.add(gen_object(name, base, members, variants))
>> + if base and not base.is_implicit():
>> + self._genh.add(gen_upcast(name, base))
>> + # TODO Worth changing the visitor signature, so we could
>> + # directly use rather than repeat type.is_implicit()?
>> if not name.startswith('q_'):
>> # implicit types won't be directly allocated/freed
>> - self._gen_type_cleanup(name)
>> + self._gen_type_cleanup(name, ifcond)
>> +
>> + def _gen_fwd_object_or_array(self, name, ifcond):
>> + with ifcontext(ifcond, self._genh):
>> + self._genh.preamble_add(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._genh.preamble_add(gen_fwd_object_or_array(name))
>> + self._gen_fwd_object_or_array(name, ifcond)
>> self._genh.add(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._genh.preamble_add(gen_fwd_object_or_array(name))
>> + self._gen_fwd_object_or_array(name, ifcond)
>> self._genh.add(gen_variants_objects(variants))
>> - self._gen_object(name, info, None, None,
>> + self._gen_object(name, info, ifcond, None,
>> [variants.tag_member], variants)
>>
>>
>> diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py
>> index 9ea2e04f81..e4a62ce030 100644
>> --- a/scripts/qapi/visit.py
>> +++ b/scripts/qapi/visit.py
>> @@ -302,29 +302,34 @@ class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor):
>> types=types))
>>
>> def visit_enum_type(self, name, info, ifcond, values, prefix):
>> - self._genh.add(gen_visit_decl(name, scalar=True))
>> - self._genc.add(gen_visit_enum(name))
>> + with ifcontext(ifcond, self._genh, self._genc):
>> + self._genh.add(gen_visit_decl(name, scalar=True))
>> + self._genc.add(gen_visit_enum(name))
>>
>> def visit_array_type(self, name, info, ifcond, element_type):
>> - self._genh.add(gen_visit_decl(name))
>> - self._genc.add(gen_visit_list(name, element_type))
>> + with ifcontext(ifcond, self._genh, self._genc):
>> + self._genh.add(gen_visit_decl(name))
>> + self._genc.add(gen_visit_list(name, element_type))
>>
>> 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._genh.add(gen_visit_members_decl(name))
>> - self._genc.add(gen_visit_object_members(name, base, members, variants))
>> - # TODO Worth changing the visitor signature, so we could
>> - # directly use rather than repeat type.is_implicit()?
>> - if not name.startswith('q_'):
>> - # only explicit types need an allocating visit
>> - self._genh.add(gen_visit_decl(name))
>> - self._genc.add(gen_visit_object(name, base, members, variants))
>> + with ifcontext(ifcond, self._genh, self._genc):
>> + self._genh.add(gen_visit_members_decl(name))
>> + self._genc.add(gen_visit_object_members(name, base,
>> + members, variants))
>> + # TODO Worth changing the visitor signature, so we could
>> + # directly use rather than repeat type.is_implicit()?
>> + if not name.startswith('q_'):
>> + # only explicit types need an allocating visit
>> + self._genh.add(gen_visit_decl(name))
>> + self._genc.add(gen_visit_object(name, base, members, variants))
>>
>> def visit_alternate_type(self, name, info, ifcond, variants):
>> - self._genh.add(gen_visit_decl(name))
>> - self._genc.add(gen_visit_alternate(name, variants))
>> + with ifcontext(ifcond, self._genh, self._genc):
>> + self._genh.add(gen_visit_decl(name))
>> + self._genc.add(gen_visit_alternate(name, variants))
>>
>>
>> def gen_visit(schema, output_dir, prefix, opt_builtins):
>
> The visit part is straightforward: wrap code generation in with
> ifcontext().
>
> The type part is more involved. First, it passes ifcond to a bunch of
> helpers, which muddies the waters a bit. Second, you can't just wrap
> object types generation, because it's recursive. You move the recursion
> out of gen_object() (previous patch), so you can wrap that. But you
> still can't wrap its new home, gen_variants_objects(). Instead, you
> bracket its call of gen_object() with gen_if() ... gen_endif(). Works,
> but is there a more direct path to the same result?
>
> I append my attempt. Its basic idea is to wrap code generation right
> where it is. Requires passing ifcond to gen_object(). The patch to
> visit.py is identical.
>
> Less churn, and I it saves me reviewing the previous patch. Opinions?
Looks good to me. I think the churn was necessary before, when we used
the function decorator. Now that we can scope the if/endif at the
block level, we don't need it anymore.
>
>
> From d6f26abe5a81b10aaff5c75db3bfc60c05203f05 Mon Sep 17 00:00:00 2001
> From: Markus Armbruster <armbru@redhat.com>
> Date: Thu, 21 Jun 2018 18:03:41 +0200
> Subject: [PATCH] qapi-types: add #if conditions to types & visitors
>
> Types & visitors are coupled and must be handled together to avoid
> temporary build regression.
>
> Wrap generated types/visitor code with #if/#endif using the context
> helpers.
>
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
I'll take it with my signed-off, since it shares a lot of similarities
with my patch.
thanks!
> ---
> scripts/qapi/types.py | 48 ++++++++++++++++++++++++++-----------------
> scripts/qapi/visit.py | 33 ++++++++++++++++-------------
> 2 files changed, 48 insertions(+), 33 deletions(-)
>
> diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py
> index 298a80db62..e43138bfd7 100644
> --- a/scripts/qapi/types.py
> +++ b/scripts/qapi/types.py
> @@ -55,7 +55,7 @@ def gen_struct_members(members):
> return ret
>
>
> -def gen_object(name, base, members, variants):
> +def gen_object(name, ifcond, base, members, variants):
> if name in objects_seen:
> return ''
> objects_seen.add(name)
> @@ -64,11 +64,14 @@ def gen_object(name, base, members, variants):
> if variants:
> for v in variants.variants:
> if isinstance(v.type, QAPISchemaObjectType):
> - ret += gen_object(v.type.name, v.type.base,
> + ret += gen_object(v.type.name, v.type.ifcond, v.type.base,
> v.type.local_members, v.type.variants)
>
> ret += mcgen('''
>
> +''')
> + ret += gen_if(ifcond)
> + ret += mcgen('''
> struct %(c_name)s {
> ''',
> c_name=c_name(name))
> @@ -101,6 +104,7 @@ struct %(c_name)s {
> ret += mcgen('''
> };
> ''')
> + ret += gen_endif(ifcond)
>
> return ret
>
> @@ -207,33 +211,39 @@ class QAPISchemaGenTypeVisitor(QAPISchemaModularCVisitor):
> self._genc.add(gen_type_cleanup(name))
>
> def visit_enum_type(self, name, info, ifcond, values, prefix):
> - self._genh.preamble_add(gen_enum(name, values, prefix))
> - self._genc.add(gen_enum_lookup(name, values, prefix))
> + with ifcontext(ifcond, self._genh, self._genc):
> + self._genh.preamble_add(gen_enum(name, values, prefix))
> + self._genc.add(gen_enum_lookup(name, values, prefix))
>
> def visit_array_type(self, name, info, ifcond, element_type):
> - self._genh.preamble_add(gen_fwd_object_or_array(name))
> - self._genh.add(gen_array(name, element_type))
> - self._gen_type_cleanup(name)
> + with ifcontext(ifcond, self._genh, self._genc):
> + self._genh.preamble_add(gen_fwd_object_or_array(name))
> + self._genh.add(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._genh.preamble_add(gen_fwd_object_or_array(name))
> - self._genh.add(gen_object(name, base, members, variants))
> - if base and not base.is_implicit():
> - self._genh.add(gen_upcast(name, base))
> - # TODO Worth changing the visitor signature, so we could
> - # directly use rather than repeat type.is_implicit()?
> - if not name.startswith('q_'):
> - # implicit types won't be directly allocated/freed
> - self._gen_type_cleanup(name)
> + with ifcontext(ifcond, self._genh):
> + self._genh.preamble_add(gen_fwd_object_or_array(name))
> + self._genh.add(gen_object(name, ifcond, base, members, variants))
> + with ifcontext(ifcond, self._genh, self._genc):
> + if base and not base.is_implicit():
> + self._genh.add(gen_upcast(name, base))
> + # TODO Worth changing the visitor signature, so we could
> + # directly use rather than repeat type.is_implicit()?
> + if not name.startswith('q_'):
> + # implicit types won't be directly allocated/freed
> + self._gen_type_cleanup(name)
>
> def visit_alternate_type(self, name, info, ifcond, variants):
> - self._genh.preamble_add(gen_fwd_object_or_array(name))
> - self._genh.add(gen_object(name, None,
> + with ifcontext(ifcond, self._genh):
> + self._genh.preamble_add(gen_fwd_object_or_array(name))
> + self._genh.add(gen_object(name, ifcond, None,
> [variants.tag_member], variants))
> - self._gen_type_cleanup(name)
> + with ifcontext(ifcond, self._genh, self._genc):
> + self._gen_type_cleanup(name)
>
>
> def gen_types(schema, output_dir, prefix, opt_builtins):
> diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py
> index 9ea2e04f81..e4a62ce030 100644
> --- a/scripts/qapi/visit.py
> +++ b/scripts/qapi/visit.py
> @@ -302,29 +302,34 @@ class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor):
> types=types))
>
> def visit_enum_type(self, name, info, ifcond, values, prefix):
> - self._genh.add(gen_visit_decl(name, scalar=True))
> - self._genc.add(gen_visit_enum(name))
> + with ifcontext(ifcond, self._genh, self._genc):
> + self._genh.add(gen_visit_decl(name, scalar=True))
> + self._genc.add(gen_visit_enum(name))
>
> def visit_array_type(self, name, info, ifcond, element_type):
> - self._genh.add(gen_visit_decl(name))
> - self._genc.add(gen_visit_list(name, element_type))
> + with ifcontext(ifcond, self._genh, self._genc):
> + self._genh.add(gen_visit_decl(name))
> + self._genc.add(gen_visit_list(name, element_type))
>
> 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._genh.add(gen_visit_members_decl(name))
> - self._genc.add(gen_visit_object_members(name, base, members, variants))
> - # TODO Worth changing the visitor signature, so we could
> - # directly use rather than repeat type.is_implicit()?
> - if not name.startswith('q_'):
> - # only explicit types need an allocating visit
> - self._genh.add(gen_visit_decl(name))
> - self._genc.add(gen_visit_object(name, base, members, variants))
> + with ifcontext(ifcond, self._genh, self._genc):
> + self._genh.add(gen_visit_members_decl(name))
> + self._genc.add(gen_visit_object_members(name, base,
> + members, variants))
> + # TODO Worth changing the visitor signature, so we could
> + # directly use rather than repeat type.is_implicit()?
> + if not name.startswith('q_'):
> + # only explicit types need an allocating visit
> + self._genh.add(gen_visit_decl(name))
> + self._genc.add(gen_visit_object(name, base, members, variants))
>
> def visit_alternate_type(self, name, info, ifcond, variants):
> - self._genh.add(gen_visit_decl(name))
> - self._genc.add(gen_visit_alternate(name, variants))
> + with ifcontext(ifcond, self._genh, self._genc):
> + self._genh.add(gen_visit_decl(name))
> + self._genc.add(gen_visit_alternate(name, variants))
>
>
> def gen_visit(schema, output_dir, prefix, opt_builtins):
> --
> 2.17.1
>
>
--
Marc-André Lureau
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 15/49] qapi: do not define enumeration value explicitely
2018-06-22 8:08 ` Markus Armbruster
@ 2018-06-27 12:13 ` Marc-André Lureau
2018-06-28 6:34 ` Markus Armbruster
0 siblings, 1 reply; 95+ messages in thread
From: Marc-André Lureau @ 2018-06-27 12:13 UTC (permalink / raw)
To: Markus Armbruster; +Cc: QEMU
Hi
On Fri, Jun 22, 2018 at 10:08 AM, Markus Armbruster <armbru@redhat.com> wrote:
> Subject: explicitly
>
> 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/common.py | 7 ++-----
>> 1 file changed, 2 insertions(+), 5 deletions(-)
>>
>> diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
>> index 60c1d0a783..68a567f53f 100644
>> --- a/scripts/qapi/common.py
>> +++ b/scripts/qapi/common.py
>> @@ -2032,14 +2032,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;
>
> What excactly in your series depends on this?
>
> What safeguards do you propose to ensure an enumeration with
> conditionals is compiled only with the exact same conditionals within
> the same program?
>
> Example of the kind of deathtrap to guard against: compile
>
> 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.
This was a trick used in previous iterations. Now that we have a
separate target schema and generated code/headers, and since we have
poisoned identifiers, this should never happen.
> Yes, I know a similar deathtrap will be set up for struct and union
> types. No excuse for ignoring either of the two.
Having gaps in the enums makes it harder to iterate over all values,
and we use more memory than necessary when allocating based on MAX
value.
It's not a big problem, but I consider this more important than this
artificially made up broken build example.
--
Marc-André Lureau
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 14/49] qapi-types: add #if conditions to types & visitors
2018-06-27 11:59 ` Marc-André Lureau
@ 2018-06-28 6:27 ` Markus Armbruster
0 siblings, 0 replies; 95+ messages in thread
From: Markus Armbruster @ 2018-06-28 6:27 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: Markus Armbruster, QEMU
Marc-André Lureau <marcandre.lureau@gmail.com> writes:
> Hi
>
> On Thu, Jun 21, 2018 at 6:12 PM, Markus Armbruster <armbru@redhat.com> wrote:
>> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>>
>>> Types & visitors are coupled and must be handled together to avoid
>>> temporary build regression.
>>>
>>> Wrap generated types/visitor code with #if/#endif using the context
>>> helpers.
>>>
>>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>>> ---
>>> scripts/qapi/types.py | 46 ++++++++++++++++++++++++++-----------------
>>> scripts/qapi/visit.py | 33 ++++++++++++++++++-------------
>>> 2 files changed, 47 insertions(+), 32 deletions(-)
>>>
>>> diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py
>>> index 3d9b0f9a07..ce4c91206c 100644
>>> --- a/scripts/qapi/types.py
>>> +++ b/scripts/qapi/types.py
>>> @@ -61,8 +61,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)
>>
>> Ignorant question out of curiosity, why is with ifcontext() not usable
>> here?
>>
>
> ifcontext() works on QAPIGen objects. We could make it work on strings
> too, but I don't think it's necessary.
I see.
>>> return ret
>>>
>>>
>>> @@ -206,41 +208,49 @@ class QAPISchemaGenTypeVisitor(QAPISchemaModularCVisitor):
>>> # gen_object() is recursive, ensure it doesn't visit the empty type
>>> objects_seen.add(schema.the_empty_object_type.name)
>>>
>>> - def _gen_type_cleanup(self, name):
>>> - self._genh.add(gen_type_cleanup_decl(name))
>>> - self._genc.add(gen_type_cleanup(name))
>>> + def _gen_type_cleanup(self, name, ifcond):
>>> + with ifcontext(ifcond, self._genh, self._genc):
>>> + self._genh.add(gen_type_cleanup_decl(name))
>>> + self._genc.add(gen_type_cleanup(name))
>>>
>>> def visit_enum_type(self, name, info, ifcond, values, prefix):
>>> - self._genh.preamble_add(gen_enum(name, values, prefix))
>>> - self._genc.add(gen_enum_lookup(name, values, prefix))
>>> + with ifcontext(ifcond, self._genh, self._genc):
>>> + self._genh.preamble_add(gen_enum(name, values, prefix))
>>> + self._genc.add(gen_enum_lookup(name, values, prefix))
>>>
>>> def visit_array_type(self, name, info, ifcond, element_type):
>>> - self._genh.preamble_add(gen_fwd_object_or_array(name))
>>> - self._genh.add(gen_array(name, element_type))
>>> - self._gen_type_cleanup(name)
>>> + with ifcontext(ifcond, self._genh):
>>> + self._genh.preamble_add(gen_fwd_object_or_array(name))
>>> + self._genh.add(gen_array(name, element_type))
>>> + self._gen_type_cleanup(name, ifcond)
>>>
>>> def _gen_object(self, name, info, ifcond, base, members, variants):
>>> - self._genh.add(gen_object(name, base, members, variants))
>>> - if base and not base.is_implicit():
>>> - self._genh.add(gen_upcast(name, base))
>>> - # TODO Worth changing the visitor signature, so we could
>>> - # directly use rather than repeat type.is_implicit()?
>>> + with ifcontext(ifcond, self._genh):
>>> + self._genh.add(gen_object(name, base, members, variants))
>>> + if base and not base.is_implicit():
>>> + self._genh.add(gen_upcast(name, base))
>>> + # TODO Worth changing the visitor signature, so we could
>>> + # directly use rather than repeat type.is_implicit()?
>>> if not name.startswith('q_'):
>>> # implicit types won't be directly allocated/freed
>>> - self._gen_type_cleanup(name)
>>> + self._gen_type_cleanup(name, ifcond)
>>> +
>>> + def _gen_fwd_object_or_array(self, name, ifcond):
>>> + with ifcontext(ifcond, self._genh):
>>> + self._genh.preamble_add(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._genh.preamble_add(gen_fwd_object_or_array(name))
>>> + self._gen_fwd_object_or_array(name, ifcond)
>>> self._genh.add(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._genh.preamble_add(gen_fwd_object_or_array(name))
>>> + self._gen_fwd_object_or_array(name, ifcond)
>>> self._genh.add(gen_variants_objects(variants))
>>> - self._gen_object(name, info, None, None,
>>> + self._gen_object(name, info, ifcond, None,
>>> [variants.tag_member], variants)
>>>
>>>
>>> diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py
>>> index 9ea2e04f81..e4a62ce030 100644
>>> --- a/scripts/qapi/visit.py
>>> +++ b/scripts/qapi/visit.py
>>> @@ -302,29 +302,34 @@ class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor):
>>> types=types))
>>>
>>> def visit_enum_type(self, name, info, ifcond, values, prefix):
>>> - self._genh.add(gen_visit_decl(name, scalar=True))
>>> - self._genc.add(gen_visit_enum(name))
>>> + with ifcontext(ifcond, self._genh, self._genc):
>>> + self._genh.add(gen_visit_decl(name, scalar=True))
>>> + self._genc.add(gen_visit_enum(name))
>>>
>>> def visit_array_type(self, name, info, ifcond, element_type):
>>> - self._genh.add(gen_visit_decl(name))
>>> - self._genc.add(gen_visit_list(name, element_type))
>>> + with ifcontext(ifcond, self._genh, self._genc):
>>> + self._genh.add(gen_visit_decl(name))
>>> + self._genc.add(gen_visit_list(name, element_type))
>>>
>>> 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._genh.add(gen_visit_members_decl(name))
>>> - self._genc.add(gen_visit_object_members(name, base, members, variants))
>>> - # TODO Worth changing the visitor signature, so we could
>>> - # directly use rather than repeat type.is_implicit()?
>>> - if not name.startswith('q_'):
>>> - # only explicit types need an allocating visit
>>> - self._genh.add(gen_visit_decl(name))
>>> - self._genc.add(gen_visit_object(name, base, members, variants))
>>> + with ifcontext(ifcond, self._genh, self._genc):
>>> + self._genh.add(gen_visit_members_decl(name))
>>> + self._genc.add(gen_visit_object_members(name, base,
>>> + members, variants))
>>> + # TODO Worth changing the visitor signature, so we could
>>> + # directly use rather than repeat type.is_implicit()?
>>> + if not name.startswith('q_'):
>>> + # only explicit types need an allocating visit
>>> + self._genh.add(gen_visit_decl(name))
>>> + self._genc.add(gen_visit_object(name, base, members, variants))
>>>
>>> def visit_alternate_type(self, name, info, ifcond, variants):
>>> - self._genh.add(gen_visit_decl(name))
>>> - self._genc.add(gen_visit_alternate(name, variants))
>>> + with ifcontext(ifcond, self._genh, self._genc):
>>> + self._genh.add(gen_visit_decl(name))
>>> + self._genc.add(gen_visit_alternate(name, variants))
>>>
>>>
>>> def gen_visit(schema, output_dir, prefix, opt_builtins):
>>
>> The visit part is straightforward: wrap code generation in with
>> ifcontext().
>>
>> The type part is more involved. First, it passes ifcond to a bunch of
>> helpers, which muddies the waters a bit. Second, you can't just wrap
>> object types generation, because it's recursive. You move the recursion
>> out of gen_object() (previous patch), so you can wrap that. But you
>> still can't wrap its new home, gen_variants_objects(). Instead, you
>> bracket its call of gen_object() with gen_if() ... gen_endif(). Works,
>> but is there a more direct path to the same result?
>>
>> I append my attempt. Its basic idea is to wrap code generation right
>> where it is. Requires passing ifcond to gen_object(). The patch to
>> visit.py is identical.
>>
>> Less churn, and I it saves me reviewing the previous patch. Opinions?
>
>
> Looks good to me. I think the churn was necessary before, when we used
> the function decorator. Now that we can scope the if/endif at the
> block level, we don't need it anymore.
Makes sense.
>> From d6f26abe5a81b10aaff5c75db3bfc60c05203f05 Mon Sep 17 00:00:00 2001
>> From: Markus Armbruster <armbru@redhat.com>
>> Date: Thu, 21 Jun 2018 18:03:41 +0200
>> Subject: [PATCH] qapi-types: add #if conditions to types & visitors
>>
>> Types & visitors are coupled and must be handled together to avoid
>> temporary build regression.
>>
>> Wrap generated types/visitor code with #if/#endif using the context
>> helpers.
>>
>> Signed-off-by: Markus Armbruster <armbru@redhat.com>
>
> I'll take it with my signed-off, since it shares a lot of similarities
> with my patch.
Of course. git-commit -avs comes from muscle memory :)
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 15/49] qapi: do not define enumeration value explicitely
2018-06-27 12:13 ` Marc-André Lureau
@ 2018-06-28 6:34 ` Markus Armbruster
0 siblings, 0 replies; 95+ messages in thread
From: Markus Armbruster @ 2018-06-28 6:34 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: Markus Armbruster, QEMU
Marc-André Lureau <marcandre.lureau@gmail.com> writes:
> Hi
>
> On Fri, Jun 22, 2018 at 10:08 AM, Markus Armbruster <armbru@redhat.com> wrote:
>> Subject: explicitly
>>
>> 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/common.py | 7 ++-----
>>> 1 file changed, 2 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
>>> index 60c1d0a783..68a567f53f 100644
>>> --- a/scripts/qapi/common.py
>>> +++ b/scripts/qapi/common.py
>>> @@ -2032,14 +2032,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;
>>
>> What excactly in your series depends on this?
>>
>> What safeguards do you propose to ensure an enumeration with
>> conditionals is compiled only with the exact same conditionals within
>> the same program?
>>
>> Example of the kind of deathtrap to guard against: compile
>>
>> 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.
>
> This was a trick used in previous iterations. Now that we have a
> separate target schema and generated code/headers, and since we have
> poisoned identifiers, this should never happen.
>
>> Yes, I know a similar deathtrap will be set up for struct and union
>> types. No excuse for ignoring either of the two.
>
> Having gaps in the enums makes it harder to iterate over all values,
> and we use more memory than necessary when allocating based on MAX
> value.
>
> It's not a big problem, but I consider this more important than this
> artificially made up broken build example.
Made up yes, but the making up comes from painful experience debugging
real programs :)
I'm not at all opposed to "contracting" enums. I just want to be
persuaded it's safe. I think your argument is "Now that we have a
separate target schema and generated code/headers, and since we have
poisoned identifiers, this should never happen." Can you elaborate?
If that goes as I expect it to go, the next request will be "now put
that into your commit message" :)
^ permalink raw reply [flat|nested] 95+ messages in thread
* Re: [Qemu-devel] [PATCH v3 05/49] qapi: leave the ifcond attribute undefined until check()
2018-06-27 5:26 ` Markus Armbruster
@ 2018-06-29 10:30 ` Marc-André Lureau
0 siblings, 0 replies; 95+ messages in thread
From: Marc-André Lureau @ 2018-06-29 10:30 UTC (permalink / raw)
To: Markus Armbruster; +Cc: QEMU
Hi
On Wed, Jun 27, 2018 at 7:26 AM, Markus Armbruster <armbru@redhat.com> wrote:
>>> This is hardly a rigorous proof. Just enough to make me believe your
>>> code works.
>>>
>>> However, I suspect adding the inheritance feature at the entity level
>>> complicates the correctness argument without real need. Can we restrict
>>> it to array elements? Have QAPISchemaArrayType.check() resolve
>>> type-valued ._ifcond, and all the others choke on it?
>>
>> There is also implicit object types.
>
> Can you give an example?
>
{ 'union': 'Foo', 'data': { 'foo': 'Test' } }
will create implicit QAPISchemaObjectType q_obj_Test-wrapper in
_make_simple_variant()
This happens before check(), so we pass the Test type as ifcond.
--
Marc-André Lureau
^ permalink raw reply [flat|nested] 95+ messages in thread
end of thread, other threads:[~2018-06-29 10:30 UTC | newest]
Thread overview: 95+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-21 11:51 [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 01/49] qapi/visit: remove useless prefix argument Marc-André Lureau
2018-06-18 14:29 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 02/49] qapi/events: generate event enum in main module Marc-André Lureau
2018-06-18 14:33 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 03/49] qapi: add 'if' to top-level expressions Marc-André Lureau
2018-06-19 7:57 ` Markus Armbruster
2018-06-19 8:41 ` Marc-André Lureau
2018-06-19 11:35 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 04/49] qapi: pass 'if' condition into QAPISchemaEntity objects Marc-André Lureau
2018-06-19 8:09 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 05/49] qapi: leave the ifcond attribute undefined until check() Marc-André Lureau
2018-06-19 9:06 ` Markus Armbruster
2018-06-26 13:39 ` Marc-André Lureau
2018-06-27 5:26 ` Markus Armbruster
2018-06-29 10:30 ` Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 06/49] qapi: add 'ifcond' to visitor methods Marc-André Lureau
2018-06-21 8:18 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 07/49] qapi: mcgen() shouldn't indent # lines Marc-André Lureau
2018-06-20 15:14 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 08/49] qapi: add #if/#endif helpers Marc-André Lureau
2018-06-20 16:01 ` Markus Armbruster
2018-06-21 7:06 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 09/49] qapi-introspect: modify to_qlit() to append ', ' on level > 0 Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 10/49] qapi-introspect: add preprocessor conditions to generated QLit Marc-André Lureau
2018-06-21 13:05 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 11/49] qapi/commands: add #if conditions to commands Marc-André Lureau
2018-06-21 14:35 ` Markus Armbruster
2018-06-22 8:34 ` Markus Armbruster
2018-06-25 13:15 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 12/49] qapi/events: add #if conditions to events Marc-André Lureau
2018-06-21 14:40 ` Markus Armbruster
2018-06-22 9:02 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 13/49] qapi-types: refactor variants handling Marc-André Lureau
2018-06-21 15:54 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 14/49] qapi-types: add #if conditions to types & visitors Marc-André Lureau
2018-06-21 16:12 ` Markus Armbruster
2018-06-27 11:59 ` Marc-André Lureau
2018-06-28 6:27 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 15/49] qapi: do not define enumeration value explicitely Marc-André Lureau
2018-06-22 8:08 ` Markus Armbruster
2018-06-27 12:13 ` Marc-André Lureau
2018-06-28 6:34 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 16/49] qapi: rename QAPISchemaEnumType.values to .members Marc-André Lureau
2018-06-22 12:24 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 17/49] qapi: change enum visitor to take QAPISchemaMember Marc-André Lureau
2018-06-22 12:24 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 18/49] tests: modify visit_enum_type() in test-qapi to print members Marc-André Lureau
2018-06-22 14:10 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 19/49] qapi: factor out check_known_keys() Marc-André Lureau
2018-06-25 14:10 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 20/49] qapi: add a dictionnary form with 'name' key for enum members Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 21/49] qapi: add 'if' to " Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 22/49] qapi-event: add 'if' condition to implicit event enum Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 23/49] qapi: rename allow_dict to allow_implicit Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 24/49] qapi: add a dictionary form with 'type' key for members Marc-André Lureau
2018-06-20 11:13 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 25/49] qapi: add 'if' to implicit struct members Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 26/49] qapi: add an error in case a discriminator is conditionnal Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 27/49] qapi: add 'if' on union members Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 28/49] qapi: add 'if' to alternate members Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 29/49] qapi: add #if conditions to generated code members Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 30/49] docs: document schema configuration Marc-André Lureau
2018-06-22 11:10 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 31/49] qapi2texi: add 'If:' section to generated documentation Marc-André Lureau
2018-06-21 16:29 ` Markus Armbruster
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 32/49] qapi2texi: add 'If:' condition to enum values Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 33/49] qapi2texi: add 'If:' condition to struct members Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 34/49] qapi2texi: add condition to variants Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 35/49] qapi: add conditions to VNC type/commands/events on the schema Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 36/49] qapi: add conditions to SPICE " Marc-André Lureau
2018-03-21 11:51 ` [Qemu-devel] [PATCH v3 37/49] qapi: add conditions to REPLICATION type/commands " Marc-André Lureau
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 38/49] build-sys: move qmp-introspect per target Marc-André Lureau
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 39/49] qapi-commands: don't initialize command list in qmp_init_marshall() Marc-André Lureau
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 40/49] RFC: qapi: learn to split schema by 'top-unit' Marc-André Lureau
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 41/49] qapi: add a top-unit 'target' schema Marc-André Lureau
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 42/49] qapi: make rtc-reset-reinjection and SEV depend on TARGET_I386 Marc-André Lureau
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 43/49] qapi: make s390 commands depend on TARGET_S390X Marc-André Lureau
2018-03-22 5:42 ` Thomas Huth
2018-03-22 9:41 ` Marc-André Lureau
2018-03-22 16:10 ` Thomas Huth
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 44/49] target.json: add a note about query-cpu* not being s390x-specific Marc-André Lureau
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 45/49] qapi: make query-gic-capabilities depend on TARGET_ARM Marc-André Lureau
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 46/49] qapi: make query-cpu-model-expansion depend on s390 or x86 Marc-André Lureau
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 47/49] qapi: make query-cpu-definitions depend on specific targets Marc-André Lureau
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 48/49] qapi: remove qmp_unregister_command() Marc-André Lureau
2018-03-21 11:52 ` [Qemu-devel] [PATCH v3 49/49] RFC: make RTC_CHANGE per-target Marc-André Lureau
2018-03-21 12:47 ` [Qemu-devel] [PATCH v3 00/49] qapi: add #if pre-processor conditions to generated code no-reply
2018-03-21 14:20 ` no-reply
2018-03-21 22:08 ` no-reply
2018-03-22 5:11 ` no-reply
2018-06-21 16:47 ` Markus Armbruster
2018-06-21 17:18 ` Marc-André Lureau
2018-06-22 6:56 ` Markus Armbruster
2018-06-22 9:06 ` 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.