mirror of https://github.com/proxmox/mirror_qemu
QAPI patches for 2020-01-14
-----BEGIN PGP SIGNATURE----- iQJGBAABCAAwFiEENUvIs9frKmtoZ05fOHC0AOuRhlMFAl4dlLoSHGFybWJydUBy ZWRoYXQuY29tAAoJEDhwtADrkYZTKGoQAKXNP/+ezGJvczU/RVtBhSQXRXQyF+zh VFznrB8gL4+MkD20bZv1jhSeNHJgQn4Frarq7IfglNy8NSLOwkVWleY9QFZV+t7U puXbO4AfIoMyvKYDEweDaHhAkQ1lnd+lDkN8HPm83EdM9ot+sGmppwnONtJm2xoC 2/+Ff+A7lmr9mU/+KVMgtnhdu8l/NdSJ4dk3gp0zPqcRtM9PanwBjA4ve+4asBxg Hec5lQlqkj09ngNtFMXTQdYvpWXXcKyBwsoJymFh6kSYA7ZACvchfvqq0SS1JQfV 4yCBfro64ZwUeWuwD5Blzb5iwrrVURRm2ecLq9uy62xmEqX72OWpl1h2+Q2HBZoZ rSbo85PJ2DTGNK+xRyRF6N7E1RGlVD4tIcE0nH/+JfW1Fkf7wCGe7AR7ywXScDav nW9UtpwPMLYHz/jO0khYAlpfY+SGtO7JFokv7R+9Zpi9IFUziyY9Y74/EIUDE8QV vk/GFbGPDUg1+aZgI3Q2/iPmgXDYWZIoBNhmebI8jwNktIyCCGWL07/I6jOX8K+/ f1njp4Bma8sFm1xoSwgJqams1SsuXdKj33V0k1Yw88RvprXBsRRMHBVtlz443/gh LtKGgqJMCU+uuDIJBZ7t1r/iNY+2bgsrgPVNf9AMtPoY+A0dP4FiUuGKEY3fkCAy h8WF8U/rkJ4/ =iRJu -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2020-01-14' into staging QAPI patches for 2020-01-14 # gpg: Signature made Tue 14 Jan 2020 10:15:22 GMT # gpg: using RSA key 354BC8B3D7EB2A6B68674E5F3870B400EB918653 # gpg: issuer "armbru@redhat.com" # gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" [full] # gpg: aka "Markus Armbruster <armbru@pond.sub.org>" [full] # Primary key fingerprint: 354B C8B3 D7EB 2A6B 6867 4E5F 3870 B400 EB91 8653 * remotes/armbru/tags/pull-qapi-2020-01-14: qapi: Simplify QAPISchemaModularCVisitor qapi: Fix code generation for empty modules qapi: Proper intermediate representation for modules qapi: Generate command registration stuff into separate files tests/Makefile.include: Fix missing test-qapi-emit-events.[ch] qapi: Tweak "command returns a nice type" check for clarity Signed-off-by: Peter Maydell <peter.maydell@linaro.org>master
commit
e021e6fe52
|
@ -37,6 +37,7 @@
|
||||||
/qapi/qapi-emit-events.[ch]
|
/qapi/qapi-emit-events.[ch]
|
||||||
/qapi/qapi-events-*.[ch]
|
/qapi/qapi-events-*.[ch]
|
||||||
/qapi/qapi-events.[ch]
|
/qapi/qapi-events.[ch]
|
||||||
|
/qapi/qapi-init-commands.[ch]
|
||||||
/qapi/qapi-introspect.[ch]
|
/qapi/qapi-introspect.[ch]
|
||||||
/qapi/qapi-types-*.[ch]
|
/qapi/qapi-types-*.[ch]
|
||||||
/qapi/qapi-types.[ch]
|
/qapi/qapi-types.[ch]
|
||||||
|
|
4
Makefile
4
Makefile
|
@ -117,6 +117,7 @@ GENERATED_QAPI_FILES += qapi/qapi-builtin-visit.h qapi/qapi-builtin-visit.c
|
||||||
GENERATED_QAPI_FILES += qapi/qapi-visit.h qapi/qapi-visit.c
|
GENERATED_QAPI_FILES += qapi/qapi-visit.h qapi/qapi-visit.c
|
||||||
GENERATED_QAPI_FILES += $(QAPI_MODULES:%=qapi/qapi-visit-%.h)
|
GENERATED_QAPI_FILES += $(QAPI_MODULES:%=qapi/qapi-visit-%.h)
|
||||||
GENERATED_QAPI_FILES += $(QAPI_MODULES:%=qapi/qapi-visit-%.c)
|
GENERATED_QAPI_FILES += $(QAPI_MODULES:%=qapi/qapi-visit-%.c)
|
||||||
|
GENERATED_QAPI_FILES += qapi/qapi-init-commands.h qapi/qapi-init-commands.c
|
||||||
GENERATED_QAPI_FILES += qapi/qapi-commands.h qapi/qapi-commands.c
|
GENERATED_QAPI_FILES += qapi/qapi-commands.h qapi/qapi-commands.c
|
||||||
GENERATED_QAPI_FILES += $(QAPI_MODULES:%=qapi/qapi-commands-%.h)
|
GENERATED_QAPI_FILES += $(QAPI_MODULES:%=qapi/qapi-commands-%.h)
|
||||||
GENERATED_QAPI_FILES += $(QAPI_MODULES:%=qapi/qapi-commands-%.c)
|
GENERATED_QAPI_FILES += $(QAPI_MODULES:%=qapi/qapi-commands-%.c)
|
||||||
|
@ -602,6 +603,7 @@ $(SRC_PATH)/scripts/qapi-gen.py
|
||||||
qga/qapi-generated/qga-qapi-types.c qga/qapi-generated/qga-qapi-types.h \
|
qga/qapi-generated/qga-qapi-types.c qga/qapi-generated/qga-qapi-types.h \
|
||||||
qga/qapi-generated/qga-qapi-visit.c qga/qapi-generated/qga-qapi-visit.h \
|
qga/qapi-generated/qga-qapi-visit.c qga/qapi-generated/qga-qapi-visit.h \
|
||||||
qga/qapi-generated/qga-qapi-commands.h qga/qapi-generated/qga-qapi-commands.c \
|
qga/qapi-generated/qga-qapi-commands.h qga/qapi-generated/qga-qapi-commands.c \
|
||||||
|
qga/qapi-generated/qga-qapi-init-commands.h qga/qapi-generated/qga-qapi-init-commands.c \
|
||||||
qga/qapi-generated/qga-qapi-doc.texi: \
|
qga/qapi-generated/qga-qapi-doc.texi: \
|
||||||
qga/qapi-generated/qapi-gen-timestamp ;
|
qga/qapi-generated/qapi-gen-timestamp ;
|
||||||
qga/qapi-generated/qapi-gen-timestamp: $(SRC_PATH)/qga/qapi-schema.json $(qapi-py)
|
qga/qapi-generated/qapi-gen-timestamp: $(SRC_PATH)/qga/qapi-schema.json $(qapi-py)
|
||||||
|
@ -620,7 +622,7 @@ qapi-gen-timestamp: $(qapi-modules) $(qapi-py)
|
||||||
"GEN","$(@:%-timestamp=%)")
|
"GEN","$(@:%-timestamp=%)")
|
||||||
@>$@
|
@>$@
|
||||||
|
|
||||||
QGALIB_GEN=$(addprefix qga/qapi-generated/, qga-qapi-types.h qga-qapi-visit.h qga-qapi-commands.h)
|
QGALIB_GEN=$(addprefix qga/qapi-generated/, qga-qapi-types.h qga-qapi-visit.h qga-qapi-commands.h qga-qapi-init-commands.h)
|
||||||
$(qga-obj-y): $(QGALIB_GEN)
|
$(qga-obj-y): $(QGALIB_GEN)
|
||||||
|
|
||||||
qemu-ga$(EXESUF): $(qga-obj-y) $(COMMON_LDADDS)
|
qemu-ga$(EXESUF): $(qga-obj-y) $(COMMON_LDADDS)
|
||||||
|
|
|
@ -1493,6 +1493,10 @@ $(prefix)qapi-commands.c: Command marshal/dispatch functions for each
|
||||||
$(prefix)qapi-commands.h: Function prototypes for the QMP commands
|
$(prefix)qapi-commands.h: Function prototypes for the QMP commands
|
||||||
specified in the schema
|
specified in the schema
|
||||||
|
|
||||||
|
$(prefix)qapi-init-commands.h - Command initialization prototype
|
||||||
|
|
||||||
|
$(prefix)qapi-init-commands.c - Command initialization code
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
$ cat qapi-generated/example-qapi-commands.h
|
$ cat qapi-generated/example-qapi-commands.h
|
||||||
|
@ -1502,11 +1506,9 @@ Example:
|
||||||
#define EXAMPLE_QAPI_COMMANDS_H
|
#define EXAMPLE_QAPI_COMMANDS_H
|
||||||
|
|
||||||
#include "example-qapi-types.h"
|
#include "example-qapi-types.h"
|
||||||
#include "qapi/qmp/dispatch.h"
|
|
||||||
|
|
||||||
UserDefOne *qmp_my_command(UserDefOneList *arg1, Error **errp);
|
UserDefOne *qmp_my_command(UserDefOneList *arg1, Error **errp);
|
||||||
void qmp_marshal_my_command(QDict *args, QObject **ret, Error **errp);
|
void qmp_marshal_my_command(QDict *args, QObject **ret, Error **errp);
|
||||||
void example_qmp_init_marshal(QmpCommandList *cmds);
|
|
||||||
|
|
||||||
#endif /* EXAMPLE_QAPI_COMMANDS_H */
|
#endif /* EXAMPLE_QAPI_COMMANDS_H */
|
||||||
$ cat qapi-generated/example-qapi-commands.c
|
$ cat qapi-generated/example-qapi-commands.c
|
||||||
|
@ -1566,7 +1568,19 @@ Example:
|
||||||
visit_end_struct(v, NULL);
|
visit_end_struct(v, NULL);
|
||||||
visit_free(v);
|
visit_free(v);
|
||||||
}
|
}
|
||||||
|
[Uninteresting stuff omitted...]
|
||||||
|
$ cat qapi-generated/example-qapi-init-commands.h
|
||||||
|
[Uninteresting stuff omitted...]
|
||||||
|
#ifndef EXAMPLE_QAPI_INIT_COMMANDS_H
|
||||||
|
#define EXAMPLE_QAPI_INIT_COMMANDS_H
|
||||||
|
|
||||||
|
#include "qapi/qmp/dispatch.h"
|
||||||
|
|
||||||
|
void example_qmp_init_marshal(QmpCommandList *cmds);
|
||||||
|
|
||||||
|
#endif /* EXAMPLE_QAPI_INIT_COMMANDS_H */
|
||||||
|
$ cat qapi-generated/example-qapi-init-commands.c
|
||||||
|
[Uninteresting stuff omitted...]
|
||||||
void example_qmp_init_marshal(QmpCommandList *cmds)
|
void example_qmp_init_marshal(QmpCommandList *cmds)
|
||||||
{
|
{
|
||||||
QTAILQ_INIT(cmds);
|
QTAILQ_INIT(cmds);
|
||||||
|
@ -1574,7 +1588,6 @@ Example:
|
||||||
qmp_register_command(cmds, "my-command",
|
qmp_register_command(cmds, "my-command",
|
||||||
qmp_marshal_my_command, QCO_NO_OPTIONS);
|
qmp_marshal_my_command, QCO_NO_OPTIONS);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Uninteresting stuff omitted...]
|
[Uninteresting stuff omitted...]
|
||||||
|
|
||||||
For a modular QAPI schema (see section Include directives), code for
|
For a modular QAPI schema (see section Include directives), code for
|
||||||
|
|
|
@ -66,8 +66,13 @@
|
||||||
#include "qemu/option.h"
|
#include "qemu/option.h"
|
||||||
#include "qemu/thread.h"
|
#include "qemu/thread.h"
|
||||||
#include "block/qapi.h"
|
#include "block/qapi.h"
|
||||||
#include "qapi/qapi-commands.h"
|
#include "qapi/qapi-commands-char.h"
|
||||||
|
#include "qapi/qapi-commands-migration.h"
|
||||||
|
#include "qapi/qapi-commands-misc.h"
|
||||||
|
#include "qapi/qapi-commands-qom.h"
|
||||||
|
#include "qapi/qapi-commands-trace.h"
|
||||||
#include "qapi/qapi-emit-events.h"
|
#include "qapi/qapi-emit-events.h"
|
||||||
|
#include "qapi/qapi-init-commands.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qapi/qmp-event.h"
|
#include "qapi/qmp-event.h"
|
||||||
#include "qapi/qapi-introspect.h"
|
#include "qapi/qapi-introspect.h"
|
||||||
|
|
|
@ -30,3 +30,4 @@ obj-y += $(QAPI_TARGET_MODULES:%=qapi-events-%.o)
|
||||||
obj-y += qapi-events.o
|
obj-y += qapi-events.o
|
||||||
obj-y += $(QAPI_TARGET_MODULES:%=qapi-commands-%.o)
|
obj-y += $(QAPI_TARGET_MODULES:%=qapi-commands-%.o)
|
||||||
obj-y += qapi-commands.o
|
obj-y += qapi-commands.o
|
||||||
|
obj-y += qapi-init-commands.o
|
||||||
|
|
|
@ -5,5 +5,6 @@ qga-obj-$(CONFIG_WIN32) += commands-win32.o channel-win32.o service-win32.o
|
||||||
qga-obj-$(CONFIG_WIN32) += vss-win32.o
|
qga-obj-$(CONFIG_WIN32) += vss-win32.o
|
||||||
qga-obj-y += qapi-generated/qga-qapi-types.o qapi-generated/qga-qapi-visit.o
|
qga-obj-y += qapi-generated/qga-qapi-types.o qapi-generated/qga-qapi-visit.o
|
||||||
qga-obj-y += qapi-generated/qga-qapi-commands.o
|
qga-obj-y += qapi-generated/qga-qapi-commands.o
|
||||||
|
qga-obj-y += qapi-generated/qga-qapi-init-commands.o
|
||||||
|
|
||||||
qga-vss-dll-obj-$(CONFIG_QGA_VSS) += vss-win32/
|
qga-vss-dll-obj-$(CONFIG_QGA_VSS) += vss-win32/
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#include "qapi/qmp/qjson.h"
|
#include "qapi/qmp/qjson.h"
|
||||||
#include "qapi/qmp/qstring.h"
|
#include "qapi/qmp/qstring.h"
|
||||||
#include "guest-agent-core.h"
|
#include "guest-agent-core.h"
|
||||||
#include "qga-qapi-commands.h"
|
#include "qga-qapi-init-commands.h"
|
||||||
#include "qapi/qmp/qerror.h"
|
#include "qapi/qmp/qerror.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "channel.h"
|
#include "channel.h"
|
||||||
|
|
|
@ -239,7 +239,7 @@ class QAPISchemaGenCommandVisitor(QAPISchemaModularCVisitor):
|
||||||
def __init__(self, prefix):
|
def __init__(self, prefix):
|
||||||
QAPISchemaModularCVisitor.__init__(
|
QAPISchemaModularCVisitor.__init__(
|
||||||
self, prefix, 'qapi-commands',
|
self, prefix, 'qapi-commands',
|
||||||
' * Schema-defined QAPI/QMP commands', __doc__)
|
' * Schema-defined QAPI/QMP commands', None, __doc__)
|
||||||
self._regy = QAPIGenCCode(None)
|
self._regy = QAPIGenCCode(None)
|
||||||
self._visited_ret_types = {}
|
self._visited_ret_types = {}
|
||||||
|
|
||||||
|
@ -263,18 +263,25 @@ class QAPISchemaGenCommandVisitor(QAPISchemaModularCVisitor):
|
||||||
commands=commands, visit=visit))
|
commands=commands, visit=visit))
|
||||||
self._genh.add(mcgen('''
|
self._genh.add(mcgen('''
|
||||||
#include "%(types)s.h"
|
#include "%(types)s.h"
|
||||||
#include "qapi/qmp/dispatch.h"
|
|
||||||
|
|
||||||
''',
|
''',
|
||||||
types=types))
|
types=types))
|
||||||
|
|
||||||
def visit_end(self):
|
def visit_end(self):
|
||||||
(genc, genh) = self._module[self._main_module]
|
self._add_system_module('init', ' * QAPI Commands initialization')
|
||||||
genh.add(mcgen('''
|
self._genh.add(mcgen('''
|
||||||
|
#include "qapi/qmp/dispatch.h"
|
||||||
|
|
||||||
void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds);
|
void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds);
|
||||||
''',
|
''',
|
||||||
c_prefix=c_name(self._prefix, protect=False)))
|
c_prefix=c_name(self._prefix, protect=False)))
|
||||||
genc.add(gen_registry(self._regy.get_content(), self._prefix))
|
self._genc.preamble_add(mcgen('''
|
||||||
|
#include "qemu/osdep.h"
|
||||||
|
#include "%(prefix)sqapi-commands.h"
|
||||||
|
#include "%(prefix)sqapi-init-commands.h"
|
||||||
|
''',
|
||||||
|
prefix=self._prefix))
|
||||||
|
self._genc.add(gen_registry(self._regy.get_content(), self._prefix))
|
||||||
|
|
||||||
def visit_command(self, name, info, ifcond, arg_type, ret_type, gen,
|
def visit_command(self, name, info, ifcond, arg_type, ret_type, gen,
|
||||||
success_response, boxed, allow_oob, allow_preconfig,
|
success_response, boxed, allow_oob, allow_preconfig,
|
||||||
|
|
|
@ -140,7 +140,7 @@ class QAPISchemaGenEventVisitor(QAPISchemaModularCVisitor):
|
||||||
def __init__(self, prefix):
|
def __init__(self, prefix):
|
||||||
QAPISchemaModularCVisitor.__init__(
|
QAPISchemaModularCVisitor.__init__(
|
||||||
self, prefix, 'qapi-events',
|
self, prefix, 'qapi-events',
|
||||||
' * Schema-defined QAPI/QMP events', __doc__)
|
' * Schema-defined QAPI/QMP events', None, __doc__)
|
||||||
self._event_enum_name = c_name(prefix + 'QAPIEvent', protect=False)
|
self._event_enum_name = c_name(prefix + 'QAPIEvent', protect=False)
|
||||||
self._event_enum_members = []
|
self._event_enum_members = []
|
||||||
self._event_emit_name = c_name(prefix + 'qapi_event_emit')
|
self._event_emit_name = c_name(prefix + 'qapi_event_emit')
|
||||||
|
|
|
@ -201,10 +201,11 @@ class QAPISchemaMonolithicCVisitor(QAPISchemaVisitor):
|
||||||
|
|
||||||
class QAPISchemaModularCVisitor(QAPISchemaVisitor):
|
class QAPISchemaModularCVisitor(QAPISchemaVisitor):
|
||||||
|
|
||||||
def __init__(self, prefix, what, blurb, pydoc):
|
def __init__(self, prefix, what, user_blurb, builtin_blurb, pydoc):
|
||||||
self._prefix = prefix
|
self._prefix = prefix
|
||||||
self._what = what
|
self._what = what
|
||||||
self._blurb = blurb
|
self._user_blurb = user_blurb
|
||||||
|
self._builtin_blurb = builtin_blurb
|
||||||
self._pydoc = pydoc
|
self._pydoc = pydoc
|
||||||
self._genc = None
|
self._genc = None
|
||||||
self._genh = None
|
self._genh = None
|
||||||
|
@ -245,7 +246,7 @@ class QAPISchemaModularCVisitor(QAPISchemaVisitor):
|
||||||
genc = QAPIGenC(basename + '.c', blurb, self._pydoc)
|
genc = QAPIGenC(basename + '.c', blurb, self._pydoc)
|
||||||
genh = QAPIGenH(basename + '.h', blurb, self._pydoc)
|
genh = QAPIGenH(basename + '.h', blurb, self._pydoc)
|
||||||
self._module[name] = (genc, genh)
|
self._module[name] = (genc, genh)
|
||||||
self._set_module(name)
|
self._genc, self._genh = self._module[name]
|
||||||
|
|
||||||
def _add_user_module(self, name, blurb):
|
def _add_user_module(self, name, blurb):
|
||||||
assert self._is_user_module(name)
|
assert self._is_user_module(name)
|
||||||
|
@ -256,9 +257,6 @@ class QAPISchemaModularCVisitor(QAPISchemaVisitor):
|
||||||
def _add_system_module(self, name, blurb):
|
def _add_system_module(self, name, blurb):
|
||||||
self._add_module(name and './' + name, blurb)
|
self._add_module(name and './' + name, blurb)
|
||||||
|
|
||||||
def _set_module(self, name):
|
|
||||||
self._genc, self._genh = self._module[name]
|
|
||||||
|
|
||||||
def write(self, output_dir, opt_builtins=False):
|
def write(self, output_dir, opt_builtins=False):
|
||||||
for name in self._module:
|
for name in self._module:
|
||||||
if self._is_builtin_module(name) and not opt_builtins:
|
if self._is_builtin_module(name) and not opt_builtins:
|
||||||
|
@ -271,15 +269,17 @@ class QAPISchemaModularCVisitor(QAPISchemaVisitor):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def visit_module(self, name):
|
def visit_module(self, name):
|
||||||
if name in self._module:
|
if name is None:
|
||||||
self._set_module(name)
|
if self._builtin_blurb:
|
||||||
elif self._is_builtin_module(name):
|
self._add_system_module(None, self._builtin_blurb)
|
||||||
|
self._begin_system_module(name)
|
||||||
|
else:
|
||||||
# The built-in module has not been created. No code may
|
# The built-in module has not been created. No code may
|
||||||
# be generated.
|
# be generated.
|
||||||
self._genc = None
|
self._genc = None
|
||||||
self._genh = None
|
self._genh = None
|
||||||
else:
|
else:
|
||||||
self._add_user_module(name, self._blurb)
|
self._add_user_module(name, self._user_blurb)
|
||||||
self._begin_user_module(name)
|
self._begin_user_module(name)
|
||||||
|
|
||||||
def visit_include(self, name, info):
|
def visit_include(self, name, info):
|
||||||
|
|
|
@ -50,9 +50,6 @@ class QAPISchemaEntity(object):
|
||||||
|
|
||||||
def check(self, schema):
|
def check(self, schema):
|
||||||
assert not self._checked
|
assert not self._checked
|
||||||
if self.info:
|
|
||||||
self._module = os.path.relpath(self.info.fname,
|
|
||||||
os.path.dirname(schema.fname))
|
|
||||||
seen = {}
|
seen = {}
|
||||||
for f in self.features:
|
for f in self.features:
|
||||||
f.check_clash(self.info, seen)
|
f.check_clash(self.info, seen)
|
||||||
|
@ -68,16 +65,19 @@ class QAPISchemaEntity(object):
|
||||||
if self.doc:
|
if self.doc:
|
||||||
self.doc.check()
|
self.doc.check()
|
||||||
|
|
||||||
|
def _set_module(self, schema, info):
|
||||||
|
assert self._checked
|
||||||
|
self._module = schema.module_by_fname(info and info.fname)
|
||||||
|
self._module.add_entity(self)
|
||||||
|
|
||||||
|
def set_module(self, schema):
|
||||||
|
self._set_module(schema, self.info)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ifcond(self):
|
def ifcond(self):
|
||||||
assert self._checked
|
assert self._checked
|
||||||
return self._ifcond
|
return self._ifcond
|
||||||
|
|
||||||
@property
|
|
||||||
def module(self):
|
|
||||||
assert self._checked
|
|
||||||
return self._module
|
|
||||||
|
|
||||||
def is_implicit(self):
|
def is_implicit(self):
|
||||||
return not self.info
|
return not self.info
|
||||||
|
|
||||||
|
@ -135,15 +135,29 @@ class QAPISchemaVisitor(object):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class QAPISchemaInclude(QAPISchemaEntity):
|
class QAPISchemaModule(object):
|
||||||
|
def __init__(self, name):
|
||||||
|
self.name = name
|
||||||
|
self._entity_list = []
|
||||||
|
|
||||||
def __init__(self, fname, info):
|
def add_entity(self, ent):
|
||||||
|
self._entity_list.append(ent)
|
||||||
|
|
||||||
|
def visit(self, visitor):
|
||||||
|
visitor.visit_module(self.name)
|
||||||
|
for entity in self._entity_list:
|
||||||
|
if visitor.visit_needed(entity):
|
||||||
|
entity.visit(visitor)
|
||||||
|
|
||||||
|
|
||||||
|
class QAPISchemaInclude(QAPISchemaEntity):
|
||||||
|
def __init__(self, sub_module, info):
|
||||||
QAPISchemaEntity.__init__(self, None, info, None)
|
QAPISchemaEntity.__init__(self, None, info, None)
|
||||||
self.fname = fname
|
self._sub_module = sub_module
|
||||||
|
|
||||||
def visit(self, visitor):
|
def visit(self, visitor):
|
||||||
QAPISchemaEntity.visit(self, visitor)
|
QAPISchemaEntity.visit(self, visitor)
|
||||||
visitor.visit_include(self.fname, self.info)
|
visitor.visit_include(self._sub_module.name, self.info)
|
||||||
|
|
||||||
|
|
||||||
class QAPISchemaType(QAPISchemaEntity):
|
class QAPISchemaType(QAPISchemaEntity):
|
||||||
|
@ -276,16 +290,14 @@ class QAPISchemaArrayType(QAPISchemaType):
|
||||||
self.info and self.info.defn_meta)
|
self.info and self.info.defn_meta)
|
||||||
assert not isinstance(self.element_type, QAPISchemaArrayType)
|
assert not isinstance(self.element_type, QAPISchemaArrayType)
|
||||||
|
|
||||||
|
def set_module(self, schema):
|
||||||
|
self._set_module(schema, self.element_type.info)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ifcond(self):
|
def ifcond(self):
|
||||||
assert self._checked
|
assert self._checked
|
||||||
return self.element_type.ifcond
|
return self.element_type.ifcond
|
||||||
|
|
||||||
@property
|
|
||||||
def module(self):
|
|
||||||
assert self._checked
|
|
||||||
return self.element_type.module
|
|
||||||
|
|
||||||
def is_implicit(self):
|
def is_implicit(self):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -711,10 +723,11 @@ class QAPISchemaCommand(QAPISchemaEntity):
|
||||||
self.ret_type = schema.resolve_type(
|
self.ret_type = schema.resolve_type(
|
||||||
self._ret_type_name, self.info, "command's 'returns'")
|
self._ret_type_name, self.info, "command's 'returns'")
|
||||||
if self.name not in self.info.pragma.returns_whitelist:
|
if self.name not in self.info.pragma.returns_whitelist:
|
||||||
if not (isinstance(self.ret_type, QAPISchemaObjectType)
|
typ = self.ret_type
|
||||||
or (isinstance(self.ret_type, QAPISchemaArrayType)
|
if isinstance(typ, QAPISchemaArrayType):
|
||||||
and isinstance(self.ret_type.element_type,
|
typ = self.ret_type.element_type
|
||||||
QAPISchemaObjectType))):
|
assert typ
|
||||||
|
if not isinstance(typ, QAPISchemaObjectType):
|
||||||
raise QAPISemError(
|
raise QAPISemError(
|
||||||
self.info,
|
self.info,
|
||||||
"command's 'returns' cannot take %s"
|
"command's 'returns' cannot take %s"
|
||||||
|
@ -782,6 +795,10 @@ class QAPISchema(object):
|
||||||
self.docs = parser.docs
|
self.docs = parser.docs
|
||||||
self._entity_list = []
|
self._entity_list = []
|
||||||
self._entity_dict = {}
|
self._entity_dict = {}
|
||||||
|
self._module_dict = {}
|
||||||
|
self._schema_dir = os.path.dirname(fname)
|
||||||
|
self._make_module(None) # built-ins
|
||||||
|
self._make_module(fname)
|
||||||
self._predefining = True
|
self._predefining = True
|
||||||
self._def_predefineds()
|
self._def_predefineds()
|
||||||
self._predefining = False
|
self._predefining = False
|
||||||
|
@ -825,14 +842,26 @@ class QAPISchema(object):
|
||||||
info, "%s uses unknown type '%s'" % (what, name))
|
info, "%s uses unknown type '%s'" % (what, name))
|
||||||
return typ
|
return typ
|
||||||
|
|
||||||
|
def _module_name(self, fname):
|
||||||
|
if fname is None:
|
||||||
|
return None
|
||||||
|
return os.path.relpath(fname, self._schema_dir)
|
||||||
|
|
||||||
|
def _make_module(self, fname):
|
||||||
|
name = self._module_name(fname)
|
||||||
|
if not name in self._module_dict:
|
||||||
|
self._module_dict[name] = QAPISchemaModule(name)
|
||||||
|
return self._module_dict[name]
|
||||||
|
|
||||||
|
def module_by_fname(self, fname):
|
||||||
|
name = self._module_name(fname)
|
||||||
|
assert name in self._module_dict
|
||||||
|
return self._module_dict[name]
|
||||||
|
|
||||||
def _def_include(self, expr, info, doc):
|
def _def_include(self, expr, info, doc):
|
||||||
include = expr['include']
|
include = expr['include']
|
||||||
assert doc is None
|
assert doc is None
|
||||||
main_info = info
|
self._def_entity(QAPISchemaInclude(self._make_module(include), info))
|
||||||
while main_info.parent:
|
|
||||||
main_info = main_info.parent
|
|
||||||
fname = os.path.relpath(include, os.path.dirname(main_info.fname))
|
|
||||||
self._def_entity(QAPISchemaInclude(fname, info))
|
|
||||||
|
|
||||||
def _def_builtin_type(self, name, json_type, c_type):
|
def _def_builtin_type(self, name, json_type, c_type):
|
||||||
self._def_entity(QAPISchemaBuiltinType(name, json_type, c_type))
|
self._def_entity(QAPISchemaBuiltinType(name, json_type, c_type))
|
||||||
|
@ -1064,15 +1093,12 @@ class QAPISchema(object):
|
||||||
ent.check(self)
|
ent.check(self)
|
||||||
ent.connect_doc()
|
ent.connect_doc()
|
||||||
ent.check_doc()
|
ent.check_doc()
|
||||||
|
for ent in self._entity_list:
|
||||||
|
ent.set_module(self)
|
||||||
|
|
||||||
def visit(self, visitor):
|
def visit(self, visitor):
|
||||||
visitor.visit_begin(self)
|
visitor.visit_begin(self)
|
||||||
module = None
|
module = None
|
||||||
visitor.visit_module(module)
|
for mod in self._module_dict.values():
|
||||||
for entity in self._entity_list:
|
mod.visit(visitor)
|
||||||
if visitor.visit_needed(entity):
|
|
||||||
if entity.module != module:
|
|
||||||
module = entity.module
|
|
||||||
visitor.visit_module(module)
|
|
||||||
entity.visit(visitor)
|
|
||||||
visitor.visit_end()
|
visitor.visit_end()
|
||||||
|
|
|
@ -243,8 +243,9 @@ class QAPISchemaGenTypeVisitor(QAPISchemaModularCVisitor):
|
||||||
def __init__(self, prefix):
|
def __init__(self, prefix):
|
||||||
QAPISchemaModularCVisitor.__init__(
|
QAPISchemaModularCVisitor.__init__(
|
||||||
self, prefix, 'qapi-types', ' * Schema-defined QAPI types',
|
self, prefix, 'qapi-types', ' * Schema-defined QAPI types',
|
||||||
__doc__)
|
' * Built-in QAPI types', __doc__)
|
||||||
self._add_system_module(None, ' * Built-in QAPI types')
|
|
||||||
|
def _begin_system_module(self, name):
|
||||||
self._genc.preamble_add(mcgen('''
|
self._genc.preamble_add(mcgen('''
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qapi/dealloc-visitor.h"
|
#include "qapi/dealloc-visitor.h"
|
||||||
|
|
|
@ -285,8 +285,9 @@ class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor):
|
||||||
def __init__(self, prefix):
|
def __init__(self, prefix):
|
||||||
QAPISchemaModularCVisitor.__init__(
|
QAPISchemaModularCVisitor.__init__(
|
||||||
self, prefix, 'qapi-visit', ' * Schema-defined QAPI visitors',
|
self, prefix, 'qapi-visit', ' * Schema-defined QAPI visitors',
|
||||||
__doc__)
|
' * Built-in QAPI visitors', __doc__)
|
||||||
self._add_system_module(None, ' * Built-in QAPI visitors')
|
|
||||||
|
def _begin_system_module(self, name):
|
||||||
self._genc.preamble_add(mcgen('''
|
self._genc.preamble_add(mcgen('''
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
|
@ -296,8 +297,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor):
|
||||||
#include "qapi/visitor.h"
|
#include "qapi/visitor.h"
|
||||||
#include "qapi/qapi-builtin-types.h"
|
#include "qapi/qapi-builtin-types.h"
|
||||||
|
|
||||||
''',
|
'''))
|
||||||
prefix=prefix))
|
|
||||||
|
|
||||||
def _begin_user_module(self, name):
|
def _begin_user_module(self, name):
|
||||||
types = self._module_basename('qapi-types', name)
|
types = self._module_basename('qapi-types', name)
|
||||||
|
|
|
@ -12,6 +12,7 @@ test-*
|
||||||
!test-*.c
|
!test-*.c
|
||||||
!docker/test-*
|
!docker/test-*
|
||||||
test-qapi-commands.[ch]
|
test-qapi-commands.[ch]
|
||||||
|
test-qapi-init-commands.[ch]
|
||||||
include/test-qapi-commands-sub-module.[ch]
|
include/test-qapi-commands-sub-module.[ch]
|
||||||
test-qapi-commands-sub-sub-module.[ch]
|
test-qapi-commands-sub-sub-module.[ch]
|
||||||
test-qapi-emit-events.[ch]
|
test-qapi-emit-events.[ch]
|
||||||
|
|
|
@ -350,8 +350,10 @@ generated-files-y += tests/test-qapi-visit.h
|
||||||
generated-files-y += tests/include/test-qapi-visit-sub-module.h
|
generated-files-y += tests/include/test-qapi-visit-sub-module.h
|
||||||
generated-files-y += tests/test-qapi-visit-sub-sub-module.h
|
generated-files-y += tests/test-qapi-visit-sub-sub-module.h
|
||||||
generated-files-y += tests/test-qapi-commands.h
|
generated-files-y += tests/test-qapi-commands.h
|
||||||
|
generated-files-y += tests/test-qapi-init-commands.h
|
||||||
generated-files-y += tests/include/test-qapi-commands-sub-module.h
|
generated-files-y += tests/include/test-qapi-commands-sub-module.h
|
||||||
generated-files-y += tests/test-qapi-commands-sub-sub-module.h
|
generated-files-y += tests/test-qapi-commands-sub-sub-module.h
|
||||||
|
generated-files-y += tests/test-qapi-emit-events.h
|
||||||
generated-files-y += tests/test-qapi-events.h
|
generated-files-y += tests/test-qapi-events.h
|
||||||
generated-files-y += tests/include/test-qapi-events-sub-module.h
|
generated-files-y += tests/include/test-qapi-events-sub-module.h
|
||||||
generated-files-y += tests/test-qapi-events-sub-sub-module.h
|
generated-files-y += tests/test-qapi-events-sub-sub-module.h
|
||||||
|
@ -465,7 +467,10 @@ tests/include/test-qapi-commands-sub-module.h \
|
||||||
tests/include/test-qapi-commands-sub-module.c \
|
tests/include/test-qapi-commands-sub-module.c \
|
||||||
tests/test-qapi-commands-sub-sub-module.h \
|
tests/test-qapi-commands-sub-sub-module.h \
|
||||||
tests/test-qapi-commands-sub-sub-module.c \
|
tests/test-qapi-commands-sub-sub-module.c \
|
||||||
|
tests/test-qapi-emit-events.c tests/test-qapi-emit-events.h \
|
||||||
tests/test-qapi-events.c tests/test-qapi-events.h \
|
tests/test-qapi-events.c tests/test-qapi-events.h \
|
||||||
|
tests/test-qapi-init-commands.c \
|
||||||
|
tests/test-qapi-init-commands.h \
|
||||||
tests/include/test-qapi-events-sub-module.c \
|
tests/include/test-qapi-events-sub-module.c \
|
||||||
tests/include/test-qapi-events-sub-module.h \
|
tests/include/test-qapi-events-sub-module.h \
|
||||||
tests/test-qapi-events-sub-sub-module.c \
|
tests/test-qapi-events-sub-sub-module.c \
|
||||||
|
@ -505,11 +510,11 @@ tests/qtest/dbus-vmstate-test.o: tests/qtest/dbus-vmstate1.h
|
||||||
|
|
||||||
tests/test-string-output-visitor$(EXESUF): tests/test-string-output-visitor.o $(test-qapi-obj-y)
|
tests/test-string-output-visitor$(EXESUF): tests/test-string-output-visitor.o $(test-qapi-obj-y)
|
||||||
tests/test-string-input-visitor$(EXESUF): tests/test-string-input-visitor.o $(test-qapi-obj-y)
|
tests/test-string-input-visitor$(EXESUF): tests/test-string-input-visitor.o $(test-qapi-obj-y)
|
||||||
tests/test-qmp-event$(EXESUF): tests/test-qmp-event.o $(test-qapi-obj-y) tests/test-qapi-events.o
|
tests/test-qmp-event$(EXESUF): tests/test-qmp-event.o $(test-qapi-obj-y) tests/test-qapi-emit-events.o tests/test-qapi-events.o
|
||||||
tests/test-qobject-output-visitor$(EXESUF): tests/test-qobject-output-visitor.o $(test-qapi-obj-y)
|
tests/test-qobject-output-visitor$(EXESUF): tests/test-qobject-output-visitor.o $(test-qapi-obj-y)
|
||||||
tests/test-clone-visitor$(EXESUF): tests/test-clone-visitor.o $(test-qapi-obj-y)
|
tests/test-clone-visitor$(EXESUF): tests/test-clone-visitor.o $(test-qapi-obj-y)
|
||||||
tests/test-qobject-input-visitor$(EXESUF): tests/test-qobject-input-visitor.o $(test-qapi-obj-y)
|
tests/test-qobject-input-visitor$(EXESUF): tests/test-qobject-input-visitor.o $(test-qapi-obj-y)
|
||||||
tests/test-qmp-cmds$(EXESUF): tests/test-qmp-cmds.o tests/test-qapi-commands.o $(test-qapi-obj-y)
|
tests/test-qmp-cmds$(EXESUF): tests/test-qmp-cmds.o tests/test-qapi-commands.o tests/test-qapi-init-commands.o $(test-qapi-obj-y)
|
||||||
tests/test-visitor-serialization$(EXESUF): tests/test-visitor-serialization.o $(test-qapi-obj-y)
|
tests/test-visitor-serialization$(EXESUF): tests/test-visitor-serialization.o $(test-qapi-obj-y)
|
||||||
tests/test-opts-visitor$(EXESUF): tests/test-opts-visitor.o $(test-qapi-obj-y)
|
tests/test-opts-visitor$(EXESUF): tests/test-opts-visitor.o $(test-qapi-obj-y)
|
||||||
|
|
||||||
|
|
|
@ -9,3 +9,4 @@ enum QType
|
||||||
member qdict
|
member qdict
|
||||||
member qlist
|
member qlist
|
||||||
member qbool
|
member qbool
|
||||||
|
module empty.json
|
||||||
|
|
|
@ -11,15 +11,13 @@ enum QType
|
||||||
member qbool
|
member qbool
|
||||||
module include-repetition.json
|
module include-repetition.json
|
||||||
include comments.json
|
include comments.json
|
||||||
|
include include-repetition-sub.json
|
||||||
|
include comments.json
|
||||||
module comments.json
|
module comments.json
|
||||||
enum Status
|
enum Status
|
||||||
member good
|
member good
|
||||||
member bad
|
member bad
|
||||||
member ugly
|
member ugly
|
||||||
module include-repetition.json
|
|
||||||
include include-repetition-sub.json
|
|
||||||
module include-repetition-sub.json
|
module include-repetition-sub.json
|
||||||
include comments.json
|
include comments.json
|
||||||
include comments.json
|
include comments.json
|
||||||
module include-repetition.json
|
|
||||||
include comments.json
|
|
||||||
|
|
|
@ -153,9 +153,6 @@ object q_obj_sizeList-wrapper
|
||||||
member data: sizeList optional=False
|
member data: sizeList optional=False
|
||||||
object q_obj_anyList-wrapper
|
object q_obj_anyList-wrapper
|
||||||
member data: anyList optional=False
|
member data: anyList optional=False
|
||||||
module sub-sub-module.json
|
|
||||||
array StatusList Status
|
|
||||||
module qapi-schema-test.json
|
|
||||||
object q_obj_StatusList-wrapper
|
object q_obj_StatusList-wrapper
|
||||||
member data: StatusList optional=False
|
member data: StatusList optional=False
|
||||||
enum UserDefListUnionKind
|
enum UserDefListUnionKind
|
||||||
|
@ -193,17 +190,6 @@ object UserDefListUnion
|
||||||
case any: q_obj_anyList-wrapper
|
case any: q_obj_anyList-wrapper
|
||||||
case user: q_obj_StatusList-wrapper
|
case user: q_obj_StatusList-wrapper
|
||||||
include include/sub-module.json
|
include include/sub-module.json
|
||||||
module include/sub-module.json
|
|
||||||
include sub-sub-module.json
|
|
||||||
module sub-sub-module.json
|
|
||||||
enum Status
|
|
||||||
member good
|
|
||||||
member bad
|
|
||||||
member ugly
|
|
||||||
module include/sub-module.json
|
|
||||||
object SecondArrayRef
|
|
||||||
member s: StatusList optional=False
|
|
||||||
module qapi-schema-test.json
|
|
||||||
command user_def_cmd None -> None
|
command user_def_cmd None -> None
|
||||||
gen=True success_response=True boxed=False oob=False preconfig=False
|
gen=True success_response=True boxed=False oob=False preconfig=False
|
||||||
object q_obj_user_def_cmd1-arg
|
object q_obj_user_def_cmd1-arg
|
||||||
|
@ -435,3 +421,13 @@ command test-command-cond-features3 None -> None
|
||||||
gen=True success_response=True boxed=False oob=False preconfig=False
|
gen=True success_response=True boxed=False oob=False preconfig=False
|
||||||
feature feature1
|
feature feature1
|
||||||
if ['defined(TEST_IF_COND_1)', 'defined(TEST_IF_COND_2)']
|
if ['defined(TEST_IF_COND_1)', 'defined(TEST_IF_COND_2)']
|
||||||
|
module include/sub-module.json
|
||||||
|
include sub-sub-module.json
|
||||||
|
object SecondArrayRef
|
||||||
|
member s: StatusList optional=False
|
||||||
|
module sub-sub-module.json
|
||||||
|
array StatusList Status
|
||||||
|
enum Status
|
||||||
|
member good
|
||||||
|
member bad
|
||||||
|
member ugly
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "tests/test-qapi-types.h"
|
#include "tests/test-qapi-types.h"
|
||||||
#include "tests/test-qapi-visit.h"
|
#include "tests/test-qapi-visit.h"
|
||||||
#include "test-qapi-commands.h"
|
#include "test-qapi-commands.h"
|
||||||
|
#include "test-qapi-init-commands.h"
|
||||||
|
|
||||||
static QmpCommandList qmp_commands;
|
static QmpCommandList qmp_commands;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue