mirror of https://gitlab.com/qemu-project/qemu
QAPI patches patches for 2021-02-08
-----BEGIN PGP SIGNATURE----- iQJGBAABCAAwFiEENUvIs9frKmtoZ05fOHC0AOuRhlMFAmAhQpISHGFybWJydUBy ZWRoYXQuY29tAAoJEDhwtADrkYZTBFYP/jh1x1Isn35q3jwjzKy6N3EYbzmaRKhW rc5bFlZLQ95Nso+Q3b8izUSeoGz7t8E+WLZBBxzNoOWBS2uC8HS0jIpUmCJaB+Yu aVrG70+5/s/BPTX7iF6LIrcRj3GIQdFEWR5Zn1V4PFk5G7NZFwEiTnViq8pLw87H c2ktAorDyH6Zl4DA2YjV0XBLPMclt53sQ/M5b6ythUq6E05bVUkQFiUm3N8joIEX 2djwumVi/dYpDwR/pVPBjPXcP5gc44y4D9sjJU6I16kyCyKi8Tr9mmEcSJFmR/Y/ GdSilmtFhxUikAQogZwi/48BhR0GawhgcKZP5IkKNjvfwqE13Vhx8/p0pEubFPUE YexvFqkSmBRZ1mT0QpCcG4lp+u6PzhTyc/gbWwPm42/T+x9fG0cDgvDZCPjIRSsg LiUmmqrwOXr+Lw6GP1Q0f0KKv5QhCfeq1YcYrEXTQsa1PDT5T8ARBzxR5O1X2UNR Xw7j4u9R63p6P5nOk5+wwRLQkUkGl7N0SYqe4thyHUfW4r48V5J9RT7ONKD2CXO9 Dw/Q3Ga1GmHaydpoZ4Az1k5kyr5dVBbAISRRWRpYA0sneg85o3RU3aTMt3r43pzC 5pjeSpx6v7K4Y3NJPL1e/j/qJZq10WtEslkF/TKcBS2qLgiKCZ1oXQPORQxxX9uK zuK8oPQR7W42 =uLm+ -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2021-02-08' into staging QAPI patches patches for 2021-02-08 # gpg: Signature made Mon 08 Feb 2021 13:54:26 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-2021-02-08: qapi: enable strict-optional checks qapi: type 'info' as Optional[QAPISourceInfo] qapi/gen: Drop support for QAPIGen without a file name qapi/commands: Simplify command registry generation qapi/gen: Support switching to another module temporarily qapi/gen: write _genc/_genh access shims qapi: centralize the built-in module name definition qapi/gen: Combine ._add_[user|system]_module qapi: use './builtin' as the built-in module name qapi: use explicitly internal module names qapi/gen: Replace ._begin_system_module() qapi: centralize is_[user|system|builtin]_module methods qapi/gen: inline _wrap_ifcond into end_if() qapi/main: handle theoretical None-return from re.match() qapi/events: fix visit_event typing qapi/commands: assert arg_type is not None Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
4f799257b3
|
@ -23,7 +23,6 @@ from typing import (
|
||||||
from .common import c_name, mcgen
|
from .common import c_name, mcgen
|
||||||
from .gen import (
|
from .gen import (
|
||||||
QAPIGenC,
|
QAPIGenC,
|
||||||
QAPIGenCCode,
|
|
||||||
QAPISchemaModularCVisitor,
|
QAPISchemaModularCVisitor,
|
||||||
build_params,
|
build_params,
|
||||||
ifcontext,
|
ifcontext,
|
||||||
|
@ -126,6 +125,9 @@ def gen_marshal(name: str,
|
||||||
boxed: bool,
|
boxed: bool,
|
||||||
ret_type: Optional[QAPISchemaType]) -> str:
|
ret_type: Optional[QAPISchemaType]) -> str:
|
||||||
have_args = boxed or (arg_type and not arg_type.is_empty())
|
have_args = boxed or (arg_type and not arg_type.is_empty())
|
||||||
|
if have_args:
|
||||||
|
assert arg_type is not None
|
||||||
|
arg_type_c_name = arg_type.c_name()
|
||||||
|
|
||||||
ret = mcgen('''
|
ret = mcgen('''
|
||||||
|
|
||||||
|
@ -147,7 +149,7 @@ def gen_marshal(name: str,
|
||||||
ret += mcgen('''
|
ret += mcgen('''
|
||||||
%(c_name)s arg = {0};
|
%(c_name)s arg = {0};
|
||||||
''',
|
''',
|
||||||
c_name=arg_type.c_name())
|
c_name=arg_type_c_name)
|
||||||
|
|
||||||
ret += mcgen('''
|
ret += mcgen('''
|
||||||
|
|
||||||
|
@ -163,7 +165,7 @@ def gen_marshal(name: str,
|
||||||
ok = visit_check_struct(v, errp);
|
ok = visit_check_struct(v, errp);
|
||||||
}
|
}
|
||||||
''',
|
''',
|
||||||
c_arg_type=arg_type.c_name())
|
c_arg_type=arg_type_c_name)
|
||||||
else:
|
else:
|
||||||
ret += mcgen('''
|
ret += mcgen('''
|
||||||
ok = visit_check_struct(v, errp);
|
ok = visit_check_struct(v, errp);
|
||||||
|
@ -193,7 +195,7 @@ out:
|
||||||
ret += mcgen('''
|
ret += mcgen('''
|
||||||
visit_type_%(c_arg_type)s_members(v, &arg, NULL);
|
visit_type_%(c_arg_type)s_members(v, &arg, NULL);
|
||||||
''',
|
''',
|
||||||
c_arg_type=arg_type.c_name())
|
c_arg_type=arg_type_c_name)
|
||||||
|
|
||||||
ret += mcgen('''
|
ret += mcgen('''
|
||||||
visit_end_struct(v, NULL);
|
visit_end_struct(v, NULL);
|
||||||
|
@ -234,28 +236,11 @@ def gen_register_command(name: str,
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def gen_registry(registry: str, prefix: str) -> str:
|
|
||||||
ret = mcgen('''
|
|
||||||
|
|
||||||
void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds)
|
|
||||||
{
|
|
||||||
QTAILQ_INIT(cmds);
|
|
||||||
|
|
||||||
''',
|
|
||||||
c_prefix=c_name(prefix, protect=False))
|
|
||||||
ret += registry
|
|
||||||
ret += mcgen('''
|
|
||||||
}
|
|
||||||
''')
|
|
||||||
return ret
|
|
||||||
|
|
||||||
|
|
||||||
class QAPISchemaGenCommandVisitor(QAPISchemaModularCVisitor):
|
class QAPISchemaGenCommandVisitor(QAPISchemaModularCVisitor):
|
||||||
def __init__(self, prefix: str):
|
def __init__(self, prefix: str):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
prefix, 'qapi-commands',
|
prefix, 'qapi-commands',
|
||||||
' * Schema-defined QAPI/QMP commands', None, __doc__)
|
' * Schema-defined QAPI/QMP commands', None, __doc__)
|
||||||
self._regy = QAPIGenCCode(None)
|
|
||||||
self._visited_ret_types: Dict[QAPIGenC, Set[QAPISchemaType]] = {}
|
self._visited_ret_types: Dict[QAPIGenC, Set[QAPISchemaType]] = {}
|
||||||
|
|
||||||
def _begin_user_module(self, name: str) -> None:
|
def _begin_user_module(self, name: str) -> None:
|
||||||
|
@ -282,25 +267,36 @@ class QAPISchemaGenCommandVisitor(QAPISchemaModularCVisitor):
|
||||||
''',
|
''',
|
||||||
types=types))
|
types=types))
|
||||||
|
|
||||||
def visit_end(self) -> None:
|
def visit_begin(self, schema: QAPISchema) -> None:
|
||||||
self._add_system_module('init', ' * QAPI Commands initialization')
|
self._add_module('./init', ' * QAPI Commands initialization')
|
||||||
self._genh.add(mcgen('''
|
self._genh.add(mcgen('''
|
||||||
#include "qapi/qmp/dispatch.h"
|
#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)))
|
||||||
self._genc.preamble_add(mcgen('''
|
self._genc.add(mcgen('''
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "%(prefix)sqapi-commands.h"
|
#include "%(prefix)sqapi-commands.h"
|
||||||
#include "%(prefix)sqapi-init-commands.h"
|
#include "%(prefix)sqapi-init-commands.h"
|
||||||
|
|
||||||
|
void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds)
|
||||||
|
{
|
||||||
|
QTAILQ_INIT(cmds);
|
||||||
|
|
||||||
''',
|
''',
|
||||||
prefix=self._prefix))
|
prefix=self._prefix,
|
||||||
self._genc.add(gen_registry(self._regy.get_content(), self._prefix))
|
c_prefix=c_name(self._prefix, protect=False)))
|
||||||
|
|
||||||
|
def visit_end(self) -> None:
|
||||||
|
with self._temp_module('./init'):
|
||||||
|
self._genc.add(mcgen('''
|
||||||
|
}
|
||||||
|
'''))
|
||||||
|
|
||||||
def visit_command(self,
|
def visit_command(self,
|
||||||
name: str,
|
name: str,
|
||||||
info: QAPISourceInfo,
|
info: Optional[QAPISourceInfo],
|
||||||
ifcond: List[str],
|
ifcond: List[str],
|
||||||
features: List[QAPISchemaFeature],
|
features: List[QAPISchemaFeature],
|
||||||
arg_type: Optional[QAPISchemaObjectType],
|
arg_type: Optional[QAPISchemaObjectType],
|
||||||
|
@ -321,15 +317,17 @@ void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds);
|
||||||
if ret_type and ret_type not in self._visited_ret_types[self._genc]:
|
if ret_type and ret_type not in self._visited_ret_types[self._genc]:
|
||||||
self._visited_ret_types[self._genc].add(ret_type)
|
self._visited_ret_types[self._genc].add(ret_type)
|
||||||
with ifcontext(ret_type.ifcond,
|
with ifcontext(ret_type.ifcond,
|
||||||
self._genh, self._genc, self._regy):
|
self._genh, self._genc):
|
||||||
self._genc.add(gen_marshal_output(ret_type))
|
self._genc.add(gen_marshal_output(ret_type))
|
||||||
with ifcontext(ifcond, self._genh, self._genc, self._regy):
|
with ifcontext(ifcond, self._genh, self._genc):
|
||||||
self._genh.add(gen_command_decl(name, arg_type, boxed, ret_type))
|
self._genh.add(gen_command_decl(name, arg_type, boxed, ret_type))
|
||||||
self._genh.add(gen_marshal_decl(name))
|
self._genh.add(gen_marshal_decl(name))
|
||||||
self._genc.add(gen_marshal(name, arg_type, boxed, ret_type))
|
self._genc.add(gen_marshal(name, arg_type, boxed, ret_type))
|
||||||
self._regy.add(gen_register_command(name, success_response,
|
with self._temp_module('./init'):
|
||||||
allow_oob, allow_preconfig,
|
with ifcontext(ifcond, self._genh, self._genc):
|
||||||
coroutine))
|
self._genc.add(gen_register_command(name, success_response,
|
||||||
|
allow_oob, allow_preconfig,
|
||||||
|
coroutine))
|
||||||
|
|
||||||
|
|
||||||
def gen_commands(schema: QAPISchema,
|
def gen_commands(schema: QAPISchema,
|
||||||
|
|
|
@ -12,7 +12,7 @@ This work is licensed under the terms of the GNU GPL, version 2.
|
||||||
See the COPYING file in the top-level directory.
|
See the COPYING file in the top-level directory.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from typing import List
|
from typing import List, Optional
|
||||||
|
|
||||||
from .common import c_enum_const, c_name, mcgen
|
from .common import c_enum_const, c_name, mcgen
|
||||||
from .gen import QAPISchemaModularCVisitor, build_params, ifcontext
|
from .gen import QAPISchemaModularCVisitor, build_params, ifcontext
|
||||||
|
@ -27,7 +27,7 @@ from .types import gen_enum, gen_enum_lookup
|
||||||
|
|
||||||
|
|
||||||
def build_event_send_proto(name: str,
|
def build_event_send_proto(name: str,
|
||||||
arg_type: QAPISchemaObjectType,
|
arg_type: Optional[QAPISchemaObjectType],
|
||||||
boxed: bool) -> str:
|
boxed: bool) -> str:
|
||||||
return 'void qapi_event_send_%(c_name)s(%(param)s)' % {
|
return 'void qapi_event_send_%(c_name)s(%(param)s)' % {
|
||||||
'c_name': c_name(name.lower()),
|
'c_name': c_name(name.lower()),
|
||||||
|
@ -35,7 +35,7 @@ def build_event_send_proto(name: str,
|
||||||
|
|
||||||
|
|
||||||
def gen_event_send_decl(name: str,
|
def gen_event_send_decl(name: str,
|
||||||
arg_type: QAPISchemaObjectType,
|
arg_type: Optional[QAPISchemaObjectType],
|
||||||
boxed: bool) -> str:
|
boxed: bool) -> str:
|
||||||
return mcgen('''
|
return mcgen('''
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ def gen_param_var(typ: QAPISchemaObjectType) -> str:
|
||||||
|
|
||||||
|
|
||||||
def gen_event_send(name: str,
|
def gen_event_send(name: str,
|
||||||
arg_type: QAPISchemaObjectType,
|
arg_type: Optional[QAPISchemaObjectType],
|
||||||
boxed: bool,
|
boxed: bool,
|
||||||
event_enum_name: str,
|
event_enum_name: str,
|
||||||
event_emit: str) -> str:
|
event_emit: str) -> str:
|
||||||
|
@ -99,6 +99,7 @@ def gen_event_send(name: str,
|
||||||
proto=build_event_send_proto(name, arg_type, boxed))
|
proto=build_event_send_proto(name, arg_type, boxed))
|
||||||
|
|
||||||
if have_args:
|
if have_args:
|
||||||
|
assert arg_type is not None
|
||||||
ret += mcgen('''
|
ret += mcgen('''
|
||||||
QObject *obj;
|
QObject *obj;
|
||||||
Visitor *v;
|
Visitor *v;
|
||||||
|
@ -114,6 +115,7 @@ def gen_event_send(name: str,
|
||||||
name=name)
|
name=name)
|
||||||
|
|
||||||
if have_args:
|
if have_args:
|
||||||
|
assert arg_type is not None
|
||||||
ret += mcgen('''
|
ret += mcgen('''
|
||||||
v = qobject_output_visitor_new(&obj);
|
v = qobject_output_visitor_new(&obj);
|
||||||
''')
|
''')
|
||||||
|
@ -189,7 +191,7 @@ class QAPISchemaGenEventVisitor(QAPISchemaModularCVisitor):
|
||||||
types=types))
|
types=types))
|
||||||
|
|
||||||
def visit_end(self) -> None:
|
def visit_end(self) -> None:
|
||||||
self._add_system_module('emit', ' * QAPI Events emission')
|
self._add_module('./emit', ' * QAPI Events emission')
|
||||||
self._genc.preamble_add(mcgen('''
|
self._genc.preamble_add(mcgen('''
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "%(prefix)sqapi-emit-events.h"
|
#include "%(prefix)sqapi-emit-events.h"
|
||||||
|
@ -211,10 +213,10 @@ void %(event_emit)s(%(event_enum)s event, QDict *qdict);
|
||||||
|
|
||||||
def visit_event(self,
|
def visit_event(self,
|
||||||
name: str,
|
name: str,
|
||||||
info: QAPISourceInfo,
|
info: Optional[QAPISourceInfo],
|
||||||
ifcond: List[str],
|
ifcond: List[str],
|
||||||
features: List[QAPISchemaFeature],
|
features: List[QAPISchemaFeature],
|
||||||
arg_type: QAPISchemaObjectType,
|
arg_type: Optional[QAPISchemaObjectType],
|
||||||
boxed: bool) -> None:
|
boxed: bool) -> None:
|
||||||
with ifcontext(ifcond, self._genh, self._genc):
|
with ifcontext(ifcond, self._genh, self._genc):
|
||||||
self._genh.add(gen_event_send_decl(name, arg_type, boxed))
|
self._genh.add(gen_event_send_decl(name, arg_type, boxed))
|
||||||
|
|
|
@ -31,12 +31,16 @@ from .common import (
|
||||||
guardstart,
|
guardstart,
|
||||||
mcgen,
|
mcgen,
|
||||||
)
|
)
|
||||||
from .schema import QAPISchemaObjectType, QAPISchemaVisitor
|
from .schema import (
|
||||||
|
QAPISchemaModule,
|
||||||
|
QAPISchemaObjectType,
|
||||||
|
QAPISchemaVisitor,
|
||||||
|
)
|
||||||
from .source import QAPISourceInfo
|
from .source import QAPISourceInfo
|
||||||
|
|
||||||
|
|
||||||
class QAPIGen:
|
class QAPIGen:
|
||||||
def __init__(self, fname: Optional[str]):
|
def __init__(self, fname: str):
|
||||||
self.fname = fname
|
self.fname = fname
|
||||||
self._preamble = ''
|
self._preamble = ''
|
||||||
self._body = ''
|
self._body = ''
|
||||||
|
@ -121,7 +125,7 @@ def build_params(arg_type: Optional[QAPISchemaObjectType],
|
||||||
|
|
||||||
|
|
||||||
class QAPIGenCCode(QAPIGen):
|
class QAPIGenCCode(QAPIGen):
|
||||||
def __init__(self, fname: Optional[str]):
|
def __init__(self, fname: str):
|
||||||
super().__init__(fname)
|
super().__init__(fname)
|
||||||
self._start_if: Optional[Tuple[List[str], str, str]] = None
|
self._start_if: Optional[Tuple[List[str], str, str]] = None
|
||||||
|
|
||||||
|
@ -130,15 +134,12 @@ class QAPIGenCCode(QAPIGen):
|
||||||
self._start_if = (ifcond, self._body, self._preamble)
|
self._start_if = (ifcond, self._body, self._preamble)
|
||||||
|
|
||||||
def end_if(self) -> None:
|
def end_if(self) -> None:
|
||||||
assert self._start_if
|
assert self._start_if is not None
|
||||||
self._wrap_ifcond()
|
|
||||||
self._start_if = None
|
|
||||||
|
|
||||||
def _wrap_ifcond(self) -> None:
|
|
||||||
self._body = _wrap_ifcond(self._start_if[0],
|
self._body = _wrap_ifcond(self._start_if[0],
|
||||||
self._start_if[1], self._body)
|
self._start_if[1], self._body)
|
||||||
self._preamble = _wrap_ifcond(self._start_if[0],
|
self._preamble = _wrap_ifcond(self._start_if[0],
|
||||||
self._start_if[2], self._preamble)
|
self._start_if[2], self._preamble)
|
||||||
|
self._start_if = None
|
||||||
|
|
||||||
def get_content(self) -> str:
|
def get_content(self) -> str:
|
||||||
assert self._start_if is None
|
assert self._start_if is None
|
||||||
|
@ -243,85 +244,88 @@ class QAPISchemaModularCVisitor(QAPISchemaVisitor):
|
||||||
self._user_blurb = user_blurb
|
self._user_blurb = user_blurb
|
||||||
self._builtin_blurb = builtin_blurb
|
self._builtin_blurb = builtin_blurb
|
||||||
self._pydoc = pydoc
|
self._pydoc = pydoc
|
||||||
self._genc: Optional[QAPIGenC] = None
|
self._current_module: Optional[str] = None
|
||||||
self._genh: Optional[QAPIGenH] = None
|
self._module: Dict[str, Tuple[QAPIGenC, QAPIGenH]] = {}
|
||||||
self._module: Dict[Optional[str], Tuple[QAPIGenC, QAPIGenH]] = {}
|
|
||||||
self._main_module: Optional[str] = None
|
self._main_module: Optional[str] = None
|
||||||
|
|
||||||
@staticmethod
|
@property
|
||||||
def _is_user_module(name: Optional[str]) -> bool:
|
def _genc(self) -> QAPIGenC:
|
||||||
return bool(name and not name.startswith('./'))
|
assert self._current_module is not None
|
||||||
|
return self._module[self._current_module][0]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _genh(self) -> QAPIGenH:
|
||||||
|
assert self._current_module is not None
|
||||||
|
return self._module[self._current_module][1]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _is_builtin_module(name: Optional[str]) -> bool:
|
def _module_dirname(name: str) -> str:
|
||||||
return not name
|
if QAPISchemaModule.is_user_module(name):
|
||||||
|
|
||||||
def _module_dirname(self, name: Optional[str]) -> str:
|
|
||||||
if self._is_user_module(name):
|
|
||||||
return os.path.dirname(name)
|
return os.path.dirname(name)
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def _module_basename(self, what: str, name: Optional[str]) -> str:
|
def _module_basename(self, what: str, name: str) -> str:
|
||||||
ret = '' if self._is_builtin_module(name) else self._prefix
|
ret = '' if QAPISchemaModule.is_builtin_module(name) else self._prefix
|
||||||
if self._is_user_module(name):
|
if QAPISchemaModule.is_user_module(name):
|
||||||
basename = os.path.basename(name)
|
basename = os.path.basename(name)
|
||||||
ret += what
|
ret += what
|
||||||
if name != self._main_module:
|
if name != self._main_module:
|
||||||
ret += '-' + os.path.splitext(basename)[0]
|
ret += '-' + os.path.splitext(basename)[0]
|
||||||
else:
|
else:
|
||||||
name = name[2:] if name else 'builtin'
|
assert QAPISchemaModule.is_system_module(name)
|
||||||
ret += re.sub(r'-', '-' + name + '-', what)
|
ret += re.sub(r'-', '-' + name[2:] + '-', what)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def _module_filename(self, what: str, name: Optional[str]) -> str:
|
def _module_filename(self, what: str, name: str) -> str:
|
||||||
return os.path.join(self._module_dirname(name),
|
return os.path.join(self._module_dirname(name),
|
||||||
self._module_basename(what, name))
|
self._module_basename(what, name))
|
||||||
|
|
||||||
def _add_module(self, name: Optional[str], blurb: str) -> None:
|
def _add_module(self, name: str, blurb: str) -> None:
|
||||||
|
if QAPISchemaModule.is_user_module(name):
|
||||||
|
if self._main_module is None:
|
||||||
|
self._main_module = name
|
||||||
basename = self._module_filename(self._what, name)
|
basename = self._module_filename(self._what, name)
|
||||||
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._genc, self._genh = self._module[name]
|
self._current_module = name
|
||||||
|
|
||||||
def _add_user_module(self, name: str, blurb: str) -> None:
|
@contextmanager
|
||||||
assert self._is_user_module(name)
|
def _temp_module(self, name: str) -> Iterator[None]:
|
||||||
if self._main_module is None:
|
old_module = self._current_module
|
||||||
self._main_module = name
|
self._current_module = name
|
||||||
self._add_module(name, blurb)
|
yield
|
||||||
|
self._current_module = old_module
|
||||||
def _add_system_module(self, name: Optional[str], blurb: str) -> None:
|
|
||||||
self._add_module(name and './' + name, blurb)
|
|
||||||
|
|
||||||
def write(self, output_dir: str, opt_builtins: bool = False) -> None:
|
def write(self, output_dir: str, opt_builtins: bool = False) -> None:
|
||||||
for name in self._module:
|
for name in self._module:
|
||||||
if self._is_builtin_module(name) and not opt_builtins:
|
if QAPISchemaModule.is_builtin_module(name) and not opt_builtins:
|
||||||
continue
|
continue
|
||||||
(genc, genh) = self._module[name]
|
(genc, genh) = self._module[name]
|
||||||
genc.write(output_dir)
|
genc.write(output_dir)
|
||||||
genh.write(output_dir)
|
genh.write(output_dir)
|
||||||
|
|
||||||
def _begin_system_module(self, name: None) -> None:
|
def _begin_builtin_module(self) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _begin_user_module(self, name: str) -> None:
|
def _begin_user_module(self, name: str) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def visit_module(self, name: Optional[str]) -> None:
|
def visit_module(self, name: str) -> None:
|
||||||
if name is None:
|
if QAPISchemaModule.is_builtin_module(name):
|
||||||
if self._builtin_blurb:
|
if self._builtin_blurb:
|
||||||
self._add_system_module(None, self._builtin_blurb)
|
self._add_module(name, self._builtin_blurb)
|
||||||
self._begin_system_module(name)
|
self._begin_builtin_module()
|
||||||
else:
|
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._current_module = None
|
||||||
self._genh = None
|
|
||||||
else:
|
else:
|
||||||
self._add_user_module(name, self._user_blurb)
|
assert QAPISchemaModule.is_user_module(name)
|
||||||
|
self._add_module(name, self._user_blurb)
|
||||||
self._begin_user_module(name)
|
self._begin_user_module(name)
|
||||||
|
|
||||||
def visit_include(self, name: str, info: QAPISourceInfo) -> None:
|
def visit_include(self, name: str, info: Optional[QAPISourceInfo]) -> None:
|
||||||
relname = os.path.relpath(self._module_filename(self._what, name),
|
relname = os.path.relpath(self._module_filename(self._what, name),
|
||||||
os.path.dirname(self._genh.fname))
|
os.path.dirname(self._genh.fname))
|
||||||
self._genh.preamble_add(mcgen('''
|
self._genh.preamble_add(mcgen('''
|
||||||
|
|
|
@ -23,6 +23,8 @@ from .visit import gen_visit
|
||||||
|
|
||||||
def invalid_prefix_char(prefix: str) -> Optional[str]:
|
def invalid_prefix_char(prefix: str) -> Optional[str]:
|
||||||
match = re.match(r'([A-Za-z_.-][A-Za-z0-9_.-]*)?', prefix)
|
match = re.match(r'([A-Za-z_.-][A-Za-z0-9_.-]*)?', prefix)
|
||||||
|
# match cannot be None, but mypy cannot infer that.
|
||||||
|
assert match is not None
|
||||||
if match.end() != len(prefix):
|
if match.end() != len(prefix):
|
||||||
return prefix[match.end()]
|
return prefix[match.end()]
|
||||||
return None
|
return None
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
[mypy]
|
[mypy]
|
||||||
strict = True
|
strict = True
|
||||||
strict_optional = False
|
|
||||||
disallow_untyped_calls = False
|
disallow_untyped_calls = False
|
||||||
python_version = 3.6
|
python_version = 3.6
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,8 @@ class QAPISchemaEntity:
|
||||||
|
|
||||||
def _set_module(self, schema, info):
|
def _set_module(self, schema, info):
|
||||||
assert self._checked
|
assert self._checked
|
||||||
self._module = schema.module_by_fname(info and info.fname)
|
fname = info.fname if info else QAPISchemaModule.BUILTIN_MODULE_NAME
|
||||||
|
self._module = schema.module_by_fname(fname)
|
||||||
self._module.add_entity(self)
|
self._module.add_entity(self)
|
||||||
|
|
||||||
def set_module(self, schema):
|
def set_module(self, schema):
|
||||||
|
@ -137,10 +138,40 @@ class QAPISchemaVisitor:
|
||||||
|
|
||||||
|
|
||||||
class QAPISchemaModule:
|
class QAPISchemaModule:
|
||||||
|
|
||||||
|
BUILTIN_MODULE_NAME = './builtin'
|
||||||
|
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
self.name = name
|
self.name = name
|
||||||
self._entity_list = []
|
self._entity_list = []
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def is_system_module(name: str) -> bool:
|
||||||
|
"""
|
||||||
|
System modules are internally defined modules.
|
||||||
|
|
||||||
|
Their names start with the "./" prefix.
|
||||||
|
"""
|
||||||
|
return name.startswith('./')
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def is_user_module(cls, name: str) -> bool:
|
||||||
|
"""
|
||||||
|
User modules are those defined by the user in qapi JSON files.
|
||||||
|
|
||||||
|
They do not start with the "./" prefix.
|
||||||
|
"""
|
||||||
|
return not cls.is_system_module(name)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def is_builtin_module(cls, name: str) -> bool:
|
||||||
|
"""
|
||||||
|
The built-in module is a single System module for the built-in types.
|
||||||
|
|
||||||
|
It is always "./builtin".
|
||||||
|
"""
|
||||||
|
return name == cls.BUILTIN_MODULE_NAME
|
||||||
|
|
||||||
def add_entity(self, ent):
|
def add_entity(self, ent):
|
||||||
self._entity_list.append(ent)
|
self._entity_list.append(ent)
|
||||||
|
|
||||||
|
@ -825,7 +856,7 @@ class QAPISchema:
|
||||||
self._entity_dict = {}
|
self._entity_dict = {}
|
||||||
self._module_dict = OrderedDict()
|
self._module_dict = OrderedDict()
|
||||||
self._schema_dir = os.path.dirname(fname)
|
self._schema_dir = os.path.dirname(fname)
|
||||||
self._make_module(None) # built-ins
|
self._make_module(QAPISchemaModule.BUILTIN_MODULE_NAME)
|
||||||
self._make_module(fname)
|
self._make_module(fname)
|
||||||
self._predefining = True
|
self._predefining = True
|
||||||
self._def_predefineds()
|
self._def_predefineds()
|
||||||
|
@ -870,9 +901,9 @@ class QAPISchema:
|
||||||
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):
|
def _module_name(self, fname: str) -> str:
|
||||||
if fname is None:
|
if QAPISchemaModule.is_system_module(fname):
|
||||||
return None
|
return fname
|
||||||
return os.path.relpath(fname, self._schema_dir)
|
return os.path.relpath(fname, self._schema_dir)
|
||||||
|
|
||||||
def _make_module(self, fname):
|
def _make_module(self, fname):
|
||||||
|
@ -883,7 +914,6 @@ class QAPISchema:
|
||||||
|
|
||||||
def module_by_fname(self, fname):
|
def module_by_fname(self, fname):
|
||||||
name = self._module_name(fname)
|
name = self._module_name(fname)
|
||||||
assert name in self._module_dict
|
|
||||||
return self._module_dict[name]
|
return self._module_dict[name]
|
||||||
|
|
||||||
def _def_include(self, expr, info, doc):
|
def _def_include(self, expr, info, doc):
|
||||||
|
|
|
@ -271,7 +271,7 @@ class QAPISchemaGenTypeVisitor(QAPISchemaModularCVisitor):
|
||||||
prefix, 'qapi-types', ' * Schema-defined QAPI types',
|
prefix, 'qapi-types', ' * Schema-defined QAPI types',
|
||||||
' * Built-in QAPI types', __doc__)
|
' * Built-in QAPI types', __doc__)
|
||||||
|
|
||||||
def _begin_system_module(self, name: None) -> None:
|
def _begin_builtin_module(self) -> None:
|
||||||
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"
|
||||||
|
@ -350,7 +350,7 @@ class QAPISchemaGenTypeVisitor(QAPISchemaModularCVisitor):
|
||||||
|
|
||||||
def visit_alternate_type(self,
|
def visit_alternate_type(self,
|
||||||
name: str,
|
name: str,
|
||||||
info: QAPISourceInfo,
|
info: Optional[QAPISourceInfo],
|
||||||
ifcond: List[str],
|
ifcond: List[str],
|
||||||
features: List[QAPISchemaFeature],
|
features: List[QAPISchemaFeature],
|
||||||
variants: QAPISchemaVariants) -> None:
|
variants: QAPISchemaVariants) -> None:
|
||||||
|
|
|
@ -305,7 +305,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor):
|
||||||
prefix, 'qapi-visit', ' * Schema-defined QAPI visitors',
|
prefix, 'qapi-visit', ' * Schema-defined QAPI visitors',
|
||||||
' * Built-in QAPI visitors', __doc__)
|
' * Built-in QAPI visitors', __doc__)
|
||||||
|
|
||||||
def _begin_system_module(self, name: None) -> None:
|
def _begin_builtin_module(self) -> None:
|
||||||
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"
|
||||||
|
@ -336,7 +336,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor):
|
||||||
|
|
||||||
def visit_enum_type(self,
|
def visit_enum_type(self,
|
||||||
name: str,
|
name: str,
|
||||||
info: QAPISourceInfo,
|
info: Optional[QAPISourceInfo],
|
||||||
ifcond: List[str],
|
ifcond: List[str],
|
||||||
features: List[QAPISchemaFeature],
|
features: List[QAPISchemaFeature],
|
||||||
members: List[QAPISchemaEnumMember],
|
members: List[QAPISchemaEnumMember],
|
||||||
|
@ -378,7 +378,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor):
|
||||||
|
|
||||||
def visit_alternate_type(self,
|
def visit_alternate_type(self,
|
||||||
name: str,
|
name: str,
|
||||||
info: QAPISourceInfo,
|
info: Optional[QAPISourceInfo],
|
||||||
ifcond: List[str],
|
ifcond: List[str],
|
||||||
features: List[QAPISchemaFeature],
|
features: List[QAPISchemaFeature],
|
||||||
variants: QAPISchemaVariants) -> None:
|
variants: QAPISchemaVariants) -> None:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
module None
|
module ./builtin
|
||||||
object q_empty
|
object q_empty
|
||||||
enum QType
|
enum QType
|
||||||
prefix QTYPE
|
prefix QTYPE
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
module None
|
module ./builtin
|
||||||
object q_empty
|
object q_empty
|
||||||
enum QType
|
enum QType
|
||||||
prefix QTYPE
|
prefix QTYPE
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
module None
|
module ./builtin
|
||||||
object q_empty
|
object q_empty
|
||||||
enum QType
|
enum QType
|
||||||
prefix QTYPE
|
prefix QTYPE
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
module None
|
module ./builtin
|
||||||
object q_empty
|
object q_empty
|
||||||
enum QType
|
enum QType
|
||||||
prefix QTYPE
|
prefix QTYPE
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
module None
|
module ./builtin
|
||||||
object q_empty
|
object q_empty
|
||||||
enum QType
|
enum QType
|
||||||
prefix QTYPE
|
prefix QTYPE
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
module None
|
module ./builtin
|
||||||
object q_empty
|
object q_empty
|
||||||
enum QType
|
enum QType
|
||||||
prefix QTYPE
|
prefix QTYPE
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
module None
|
module ./builtin
|
||||||
object q_empty
|
object q_empty
|
||||||
enum QType
|
enum QType
|
||||||
prefix QTYPE
|
prefix QTYPE
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
module None
|
module ./builtin
|
||||||
object q_empty
|
object q_empty
|
||||||
enum QType
|
enum QType
|
||||||
prefix QTYPE
|
prefix QTYPE
|
||||||
|
|
Loading…
Reference in New Issue