aboutsummaryrefslogtreecommitdiff
path: root/scripts/qapi.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/qapi.py')
-rw-r--r--scripts/qapi.py63
1 files changed, 50 insertions, 13 deletions
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 0c6159c400..21bc32fda3 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -522,10 +522,14 @@ def check_type(expr_info, source, value, allow_array=False,
def check_command(expr, expr_info):
name = expr['command']
+ boxed = expr.get('boxed', False)
+ args_meta = ['struct']
+ if boxed:
+ args_meta += ['union', 'alternate']
check_type(expr_info, "'data' for command '%s'" % name,
- expr.get('data'), allow_dict=True, allow_optional=True,
- allow_metas=['struct'])
+ expr.get('data'), allow_dict=not boxed, allow_optional=True,
+ allow_metas=args_meta)
returns_meta = ['union', 'struct']
if name in returns_whitelist:
returns_meta += ['built-in', 'alternate', 'enum']
@@ -537,11 +541,15 @@ def check_command(expr, expr_info):
def check_event(expr, expr_info):
global events
name = expr['event']
+ boxed = expr.get('boxed', False)
+ meta = ['struct']
+ if boxed:
+ meta += ['union', 'alternate']
events.append(name)
check_type(expr_info, "'data' for event '%s'" % name,
- expr.get('data'), allow_dict=True, allow_optional=True,
- allow_metas=['struct'])
+ expr.get('data'), allow_dict=not boxed, allow_optional=True,
+ allow_metas=meta)
def check_union(expr, expr_info):
@@ -694,6 +702,10 @@ def check_keys(expr_elem, meta, required, optional=[]):
raise QAPIExprError(info,
"'%s' of %s '%s' should only use false value"
% (key, meta, name))
+ if key == 'boxed' and value is not True:
+ raise QAPIExprError(info,
+ "'%s' of %s '%s' should only use true value"
+ % (key, meta, name))
for key in required:
if key not in expr:
raise QAPIExprError(info,
@@ -725,10 +737,10 @@ def check_exprs(exprs):
add_struct(expr, info)
elif 'command' in expr:
check_keys(expr_elem, 'command', [],
- ['data', 'returns', 'gen', 'success-response'])
+ ['data', 'returns', 'gen', 'success-response', 'boxed'])
add_name(expr['command'], info, 'command')
elif 'event' in expr:
- check_keys(expr_elem, 'event', [], ['data'])
+ check_keys(expr_elem, 'event', [], ['data', 'boxed'])
add_name(expr['event'], info, 'event')
else:
raise QAPIExprError(expr_elem['info'],
@@ -1163,6 +1175,9 @@ class QAPISchemaAlternateType(QAPISchemaType):
def visit(self, visitor):
visitor.visit_alternate_type(self.name, self.info, self.variants)
+ def is_empty(self):
+ return False
+
class QAPISchemaCommand(QAPISchemaEntity):
def __init__(self, name, info, arg_type, ret_type, gen, success_response,
@@ -1181,9 +1196,19 @@ class QAPISchemaCommand(QAPISchemaEntity):
def check(self, schema):
if self._arg_type_name:
self.arg_type = schema.lookup_type(self._arg_type_name)
- assert isinstance(self.arg_type, QAPISchemaObjectType)
- assert not self.arg_type.variants # not implemented
- assert not self.boxed # not implemented
+ assert (isinstance(self.arg_type, QAPISchemaObjectType) or
+ isinstance(self.arg_type, QAPISchemaAlternateType))
+ self.arg_type.check(schema)
+ if self.boxed:
+ if self.arg_type.is_empty():
+ raise QAPIExprError(self.info,
+ "Cannot use 'boxed' with empty type")
+ else:
+ assert not isinstance(self.arg_type, QAPISchemaAlternateType)
+ assert not self.arg_type.variants
+ elif self.boxed:
+ raise QAPIExprError(self.info,
+ "Use of 'boxed' requires 'data'")
if self._ret_type_name:
self.ret_type = schema.lookup_type(self._ret_type_name)
assert isinstance(self.ret_type, QAPISchemaType)
@@ -1205,9 +1230,19 @@ class QAPISchemaEvent(QAPISchemaEntity):
def check(self, schema):
if self._arg_type_name:
self.arg_type = schema.lookup_type(self._arg_type_name)
- assert isinstance(self.arg_type, QAPISchemaObjectType)
- assert not self.arg_type.variants # not implemented
- assert not self.boxed # not implemented
+ assert (isinstance(self.arg_type, QAPISchemaObjectType) or
+ isinstance(self.arg_type, QAPISchemaAlternateType))
+ self.arg_type.check(schema)
+ if self.boxed:
+ if self.arg_type.is_empty():
+ raise QAPIExprError(self.info,
+ "Cannot use 'boxed' with empty type")
+ else:
+ assert not isinstance(self.arg_type, QAPISchemaAlternateType)
+ assert not self.arg_type.variants
+ elif self.boxed:
+ raise QAPIExprError(self.info,
+ "Use of 'boxed' requires 'data'")
def visit(self, visitor):
visitor.visit_event(self.name, self.info, self.arg_type, self.boxed)
@@ -1648,11 +1683,13 @@ extern const char *const %(c_name)s_lookup[];
def gen_params(arg_type, boxed, extra):
if not arg_type:
+ assert not boxed
return extra
ret = ''
sep = ''
if boxed:
- assert False # not implemented
+ ret += '%s arg' % arg_type.c_param_type()
+ sep = ', '
else:
assert not arg_type.variants
for memb in arg_type.members: