diff options
author | Markus Armbruster <armbru@redhat.com> | 2020-03-17 12:54:37 +0100 |
---|---|---|
committer | Markus Armbruster <armbru@redhat.com> | 2020-03-17 19:58:34 +0100 |
commit | 013b4efc9be9af8276bd891cd52267d409f1d712 (patch) | |
tree | 78d9eb2e1a277349ba13511542581b1edd39edca /scripts | |
parent | e4405b30695cda6fad69a4411c05b73d538c7992 (diff) |
qapi: Add feature flags to remaining definitions
In v4.1.0, we added feature flags just to struct types (commit
6a8c0b5102^..f3ed93d545), to satisfy an immediate need (commit
c9d4070991 "file-posix: Add dynamic-auto-read-only QAPI feature"). In
v4.2.0, we added them to commands (commit 23394b4c39 "qapi: Add
feature flags to commands") to satisfy another immediate need (commit
d76744e65e "qapi: Allow introspecting fix for savevm's cooperation
with blockdev").
Add them to the remaining definitions: enumeration types, union types,
alternate types, and events.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <20200317115459.31821-13-armbru@redhat.com>
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/qapi/doc.py | 6 | ||||
-rw-r--r-- | scripts/qapi/events.py | 2 | ||||
-rw-r--r-- | scripts/qapi/expr.py | 11 | ||||
-rw-r--r-- | scripts/qapi/introspect.py | 31 | ||||
-rw-r--r-- | scripts/qapi/schema.py | 96 | ||||
-rw-r--r-- | scripts/qapi/types.py | 4 | ||||
-rw-r--r-- | scripts/qapi/visit.py | 4 |
7 files changed, 80 insertions, 74 deletions
diff --git a/scripts/qapi/doc.py b/scripts/qapi/doc.py index 1787a53d91..36e823338b 100644 --- a/scripts/qapi/doc.py +++ b/scripts/qapi/doc.py @@ -243,7 +243,7 @@ class QAPISchemaGenDocVisitor(QAPISchemaVisitor): def write(self, output_dir): self._gen.write(output_dir) - def visit_enum_type(self, name, info, ifcond, members, prefix): + def visit_enum_type(self, name, info, ifcond, features, members, prefix): doc = self.cur_doc self._gen.add(texi_type('Enum', doc, ifcond, texi_members(doc, 'Values', @@ -257,7 +257,7 @@ class QAPISchemaGenDocVisitor(QAPISchemaVisitor): self._gen.add(texi_type('Object', doc, ifcond, texi_members(doc, 'Members', base, variants))) - def visit_alternate_type(self, name, info, ifcond, variants): + def visit_alternate_type(self, name, info, ifcond, features, variants): doc = self.cur_doc self._gen.add(texi_type('Alternate', doc, ifcond, texi_members(doc, 'Members'))) @@ -270,7 +270,7 @@ class QAPISchemaGenDocVisitor(QAPISchemaVisitor): texi_arguments(doc, arg_type if boxed else None))) - def visit_event(self, name, info, ifcond, arg_type, boxed): + def visit_event(self, name, info, ifcond, features, arg_type, boxed): doc = self.cur_doc self._gen.add(texi_msg('Event', doc, ifcond, texi_arguments(doc, diff --git a/scripts/qapi/events.py b/scripts/qapi/events.py index a98b9f5099..b544af5a1c 100644 --- a/scripts/qapi/events.py +++ b/scripts/qapi/events.py @@ -189,7 +189,7 @@ void %(event_emit)s(%(event_enum)s event, QDict *qdict); event_emit=self._event_emit_name, event_enum=self._event_enum_name)) - def visit_event(self, name, info, ifcond, arg_type, boxed): + def visit_event(self, name, info, ifcond, features, 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, diff --git a/scripts/qapi/expr.py b/scripts/qapi/expr.py index fecf466fa7..f9c4448980 100644 --- a/scripts/qapi/expr.py +++ b/scripts/qapi/expr.py @@ -219,7 +219,6 @@ def check_struct(expr, info): check_type(members, info, "'data'", allow_dict=name) check_type(expr.get('base'), info, "'base'") - check_features(expr.get('features'), info) def check_union(expr, info): @@ -267,7 +266,6 @@ def check_command(expr, info): raise QAPISemError(info, "'boxed': true requires 'data'") check_type(args, info, "'data'", allow_dict=not boxed) check_type(rets, info, "'returns'", allow_array=True) - check_features(expr.get('features'), info) def check_event(expr, info): @@ -319,18 +317,18 @@ def check_exprs(exprs): if meta == 'enum': check_keys(expr, info, meta, - ['enum', 'data'], ['if', 'prefix']) + ['enum', 'data'], ['if', 'features', 'prefix']) check_enum(expr, info) elif meta == 'union': check_keys(expr, info, meta, ['union', 'data'], - ['base', 'discriminator', 'if']) + ['base', 'discriminator', 'if', 'features']) normalize_members(expr.get('base')) normalize_members(expr['data']) check_union(expr, info) elif meta == 'alternate': check_keys(expr, info, meta, - ['alternate', 'data'], ['if']) + ['alternate', 'data'], ['if', 'features']) normalize_members(expr['data']) check_alternate(expr, info) elif meta == 'struct': @@ -348,13 +346,14 @@ def check_exprs(exprs): check_command(expr, info) elif meta == 'event': check_keys(expr, info, meta, - ['event'], ['data', 'boxed', 'if']) + ['event'], ['data', 'boxed', 'if', 'features']) normalize_members(expr.get('data')) check_event(expr, info) else: assert False, 'unexpected meta type' check_if(expr, info, meta) + check_features(expr.get('features'), info) check_flags(expr, info) return exprs diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py index b5537eddc0..2e9e00aa1f 100644 --- a/scripts/qapi/introspect.py +++ b/scripts/qapi/introspect.py @@ -144,7 +144,7 @@ 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, ifcond): + def _gen_qlit(self, name, mtype, obj, ifcond, features): extra = {} if mtype not in ('command', 'event', 'builtin', 'array'): if not self._unmask: @@ -154,6 +154,8 @@ const QLitObject %(c_name)s = %(c_string)s; name = self._name(name) obj['name'] = name obj['meta-type'] = mtype + if features: + obj['features'] = [(f.name, {'if': f.ifcond}) for f in features] if ifcond: extra['if'] = ifcond if extra: @@ -178,18 +180,18 @@ const QLitObject %(c_name)s = %(c_string)s; {'if': variant.ifcond}) def visit_builtin_type(self, name, info, json_type): - self._gen_qlit(name, 'builtin', {'json-type': json_type}, []) + self._gen_qlit(name, 'builtin', {'json-type': json_type}, [], None) - def visit_enum_type(self, name, info, ifcond, members, prefix): + def visit_enum_type(self, name, info, ifcond, features, members, prefix): self._gen_qlit(name, 'enum', {'values': [(m.name, {'if': m.ifcond}) for m in members]}, - ifcond) + ifcond, features) def visit_array_type(self, name, info, ifcond, element_type): element = self._use_type(element_type) self._gen_qlit('[' + element + ']', 'array', {'element-type': element}, - ifcond) + ifcond, None) def visit_object_type_flat(self, name, info, ifcond, members, variants, features): @@ -197,16 +199,15 @@ const QLitObject %(c_name)s = %(c_string)s; if variants: obj.update(self._gen_variants(variants.tag_member.name, variants.variants)) - if features: - obj['features'] = [(f.name, {'if': f.ifcond}) for f in features] - self._gen_qlit(name, 'object', obj, ifcond) + self._gen_qlit(name, 'object', obj, ifcond, features) - def visit_alternate_type(self, name, info, ifcond, variants): + def visit_alternate_type(self, name, info, ifcond, features, variants): self._gen_qlit(name, 'alternate', {'members': [ ({'type': self._use_type(m.type)}, {'if': m.ifcond}) - for m in variants.variants]}, ifcond) + for m in variants.variants]}, + ifcond, features) def visit_command(self, name, info, ifcond, arg_type, ret_type, gen, success_response, boxed, allow_oob, allow_preconfig, @@ -217,16 +218,12 @@ const QLitObject %(c_name)s = %(c_string)s; 'ret-type': self._use_type(ret_type)} if allow_oob: obj['allow-oob'] = allow_oob + self._gen_qlit(name, 'command', obj, ifcond, features) - if features: - obj['features'] = [(f.name, {'if': f.ifcond}) for f in features] - - self._gen_qlit(name, 'command', obj, ifcond) - - def visit_event(self, name, info, ifcond, arg_type, boxed): + def visit_event(self, name, info, ifcond, features, 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)}, - ifcond) + ifcond, features) def gen_introspect(schema, output_dir, prefix, opt_unmask): diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index 2a2b495987..22238005ff 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -109,7 +109,7 @@ class QAPISchemaVisitor: def visit_builtin_type(self, name, info, json_type): pass - def visit_enum_type(self, name, info, ifcond, members, prefix): + def visit_enum_type(self, name, info, ifcond, features, members, prefix): pass def visit_array_type(self, name, info, ifcond, element_type): @@ -123,7 +123,7 @@ class QAPISchemaVisitor: features): pass - def visit_alternate_type(self, name, info, ifcond, variants): + def visit_alternate_type(self, name, info, ifcond, features, variants): pass def visit_command(self, name, info, ifcond, arg_type, ret_type, gen, @@ -131,7 +131,7 @@ class QAPISchemaVisitor: features): pass - def visit_event(self, name, info, ifcond, arg_type, boxed): + def visit_event(self, name, info, ifcond, features, arg_type, boxed): pass @@ -234,8 +234,8 @@ class QAPISchemaBuiltinType(QAPISchemaType): class QAPISchemaEnumType(QAPISchemaType): meta = 'enum' - def __init__(self, name, info, doc, ifcond, members, prefix): - super().__init__(name, info, doc, ifcond) + def __init__(self, name, info, doc, ifcond, features, members, prefix): + super().__init__(name, info, doc, ifcond, features) for m in members: assert isinstance(m, QAPISchemaEnumMember) m.set_defined_in(name) @@ -271,15 +271,16 @@ class QAPISchemaEnumType(QAPISchemaType): def visit(self, visitor): super().visit(visitor) - visitor.visit_enum_type(self.name, self.info, self.ifcond, - self.members, self.prefix) + visitor.visit_enum_type( + self.name, self.info, self.ifcond, self.features, + self.members, self.prefix) class QAPISchemaArrayType(QAPISchemaType): meta = 'array' def __init__(self, name, info, element_type): - super().__init__(name, info, None, None) + super().__init__(name, info, None) assert isinstance(element_type, str) self._element_type_name = element_type self.element_type = None @@ -325,8 +326,8 @@ class QAPISchemaArrayType(QAPISchemaType): class QAPISchemaObjectType(QAPISchemaType): - def __init__(self, name, info, doc, ifcond, - base, local_members, variants, features): + def __init__(self, name, info, doc, ifcond, features, + 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 @@ -622,8 +623,8 @@ class QAPISchemaObjectTypeVariant(QAPISchemaObjectTypeMember): class QAPISchemaAlternateType(QAPISchemaType): meta = 'alternate' - def __init__(self, name, info, doc, ifcond, variants): - super().__init__(name, info, doc, ifcond) + def __init__(self, name, info, doc, ifcond, features, variants): + super().__init__(name, info, doc, ifcond, features) assert isinstance(variants, QAPISchemaObjectTypeVariants) assert variants.tag_member variants.set_defined_in(name) @@ -683,16 +684,16 @@ class QAPISchemaAlternateType(QAPISchemaType): def visit(self, visitor): super().visit(visitor) - visitor.visit_alternate_type(self.name, self.info, self.ifcond, - self.variants) + visitor.visit_alternate_type( + self.name, self.info, self.ifcond, self.features, self.variants) class QAPISchemaCommand(QAPISchemaEntity): meta = 'command' - def __init__(self, name, info, doc, ifcond, arg_type, ret_type, - gen, success_response, boxed, allow_oob, allow_preconfig, - features): + def __init__(self, name, info, doc, ifcond, features, + arg_type, ret_type, + gen, success_response, boxed, allow_oob, allow_preconfig): super().__init__(name, info, doc, ifcond, features) assert not arg_type or isinstance(arg_type, str) assert not ret_type or isinstance(ret_type, str) @@ -755,8 +756,8 @@ class QAPISchemaCommand(QAPISchemaEntity): class QAPISchemaEvent(QAPISchemaEntity): meta = 'event' - def __init__(self, name, info, doc, ifcond, arg_type, boxed): - super().__init__(name, info, doc, ifcond) + def __init__(self, name, info, doc, ifcond, features, arg_type, boxed): + super().__init__(name, info, doc, ifcond, features) assert not arg_type or isinstance(arg_type, str) self._arg_type_name = arg_type self.arg_type = None @@ -787,8 +788,9 @@ class QAPISchemaEvent(QAPISchemaEntity): def visit(self, visitor): super().visit(visitor) - visitor.visit_event(self.name, self.info, self.ifcond, - self.arg_type, self.boxed) + visitor.visit_event( + self.name, self.info, self.ifcond, self.features, + self.arg_type, self.boxed) class QAPISchema: @@ -893,7 +895,7 @@ class QAPISchema: ('null', 'null', 'QNull' + pointer_suffix)]: self._def_builtin_type(*t) self.the_empty_object_type = QAPISchemaObjectType( - 'q_empty', None, None, None, None, [], None, []) + 'q_empty', None, None, None, None, None, [], None) self._def_entity(self.the_empty_object_type) qtypes = ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', @@ -901,10 +903,11 @@ class QAPISchema: qtype_values = self._make_enum_members( [{'name': n} for n in qtypes], None) - self._def_entity(QAPISchemaEnumType('QType', None, None, None, + self._def_entity(QAPISchemaEnumType('QType', None, None, None, None, qtype_values, 'QTYPE')) - def _make_features(self, features, info): + def _make_features(self, expr, info): + features = expr.get('features', []) return [QAPISchemaFeature(f['name'], info, f.get('if')) for f in features] @@ -916,7 +919,8 @@ class QAPISchema: # See also QAPISchemaObjectTypeMember.describe() name = name + 'Kind' # reserved by check_defn_name_str() self._def_entity(QAPISchemaEnumType( - name, info, None, ifcond, self._make_enum_members(values, info), + name, info, None, ifcond, None, + self._make_enum_members(values, info), None)) return name @@ -944,8 +948,8 @@ class QAPISchema: # TODO kill simple unions or implement the disjunction assert (ifcond or []) == typ._ifcond # pylint: disable=protected-access else: - self._def_entity(QAPISchemaObjectType(name, info, None, ifcond, - None, members, None, [])) + self._def_entity(QAPISchemaObjectType( + name, info, None, ifcond, None, None, members, None)) return name def _def_enum_type(self, expr, info, doc): @@ -953,8 +957,9 @@ class QAPISchema: data = expr['data'] prefix = expr.get('prefix') ifcond = expr.get('if') + features = self._make_features(expr, info) self._def_entity(QAPISchemaEnumType( - name, info, doc, ifcond, + name, info, doc, ifcond, features, self._make_enum_members(data, info), prefix)) def _make_member(self, name, typ, ifcond, info): @@ -976,12 +981,11 @@ class QAPISchema: base = expr.get('base') data = expr['data'] ifcond = expr.get('if') - features = expr.get('features', []) + features = self._make_features(expr, info) self._def_entity(QAPISchemaObjectType( - name, info, doc, ifcond, base, + name, info, doc, ifcond, features, base, self._make_members(data, info), - None, - self._make_features(features, info))) + None)) def _make_variant(self, case, typ, ifcond, info): return QAPISchemaObjectTypeVariant(case, info, typ, ifcond) @@ -1000,6 +1004,7 @@ class QAPISchema: data = expr['data'] base = expr.get('base') ifcond = expr.get('if') + features = self._make_features(expr, info) tag_name = expr.get('discriminator') tag_member = None if isinstance(base, dict): @@ -1020,21 +1025,22 @@ class QAPISchema: tag_member = QAPISchemaObjectTypeMember('type', info, typ, False) members = [tag_member] self._def_entity( - QAPISchemaObjectType(name, info, doc, ifcond, base, members, + QAPISchemaObjectType(name, info, doc, ifcond, features, + base, members, QAPISchemaObjectTypeVariants( - tag_name, info, tag_member, variants), - [])) + tag_name, info, tag_member, variants))) def _def_alternate_type(self, expr, info, doc): name = expr['alternate'] data = expr['data'] ifcond = expr.get('if') + features = self._make_features(expr, info) variants = [self._make_variant(key, value['type'], value.get('if'), info) for (key, value) in data.items()] tag_member = QAPISchemaObjectTypeMember('type', info, 'QType', False) self._def_entity( - QAPISchemaAlternateType(name, info, doc, ifcond, + QAPISchemaAlternateType(name, info, doc, ifcond, features, QAPISchemaObjectTypeVariants( None, info, tag_member, variants))) @@ -1048,27 +1054,31 @@ class QAPISchema: allow_oob = expr.get('allow-oob', False) allow_preconfig = expr.get('allow-preconfig', False) ifcond = expr.get('if') - features = expr.get('features', []) + features = self._make_features(expr, info) if isinstance(data, OrderedDict): data = self._make_implicit_object_type( - name, info, ifcond, 'arg', self._make_members(data, info)) + name, info, 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, ifcond, data, rets, + self._def_entity(QAPISchemaCommand(name, info, doc, ifcond, features, + data, rets, gen, success_response, - boxed, allow_oob, allow_preconfig, - self._make_features(features, info))) + boxed, allow_oob, allow_preconfig)) def _def_event(self, expr, info, doc): name = expr['event'] data = expr.get('data') boxed = expr.get('boxed', False) ifcond = expr.get('if') + features = self._make_features(expr, info) if isinstance(data, OrderedDict): data = self._make_implicit_object_type( - name, info, ifcond, 'arg', self._make_members(data, info)) - self._def_entity(QAPISchemaEvent(name, info, doc, ifcond, data, boxed)) + name, info, ifcond, + 'arg', self._make_members(data, info)) + self._def_entity(QAPISchemaEvent(name, info, doc, ifcond, features, + data, boxed)) def _def_exprs(self, exprs): for expr_elem in exprs: diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py index 3c83b6e4be..d0d5c03646 100644 --- a/scripts/qapi/types.py +++ b/scripts/qapi/types.py @@ -278,7 +278,7 @@ 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, members, prefix): + def visit_enum_type(self, name, info, ifcond, features, members, prefix): with ifcontext(ifcond, self._genh, self._genc): self._genh.preamble_add(gen_enum(name, members, prefix)) self._genc.add(gen_enum_lookup(name, members, prefix)) @@ -306,7 +306,7 @@ class QAPISchemaGenTypeVisitor(QAPISchemaModularCVisitor): # implicit types won't be directly allocated/freed self._gen_type_cleanup(name) - def visit_alternate_type(self, name, info, ifcond, variants): + def visit_alternate_type(self, name, info, ifcond, features, variants): with ifcontext(ifcond, self._genh): self._genh.preamble_add(gen_fwd_object_or_array(name)) self._genh.add(gen_object(name, ifcond, None, diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py index 421e5bd8cd..6e5ed781d7 100644 --- a/scripts/qapi/visit.py +++ b/scripts/qapi/visit.py @@ -316,7 +316,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor): ''', types=types)) - def visit_enum_type(self, name, info, ifcond, members, prefix): + def visit_enum_type(self, name, info, ifcond, features, 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)) @@ -342,7 +342,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, ifcond, variants): + def visit_alternate_type(self, name, info, ifcond, features, variants): with ifcontext(ifcond, self._genh, self._genc): self._genh.add(gen_visit_decl(name)) self._genc.add(gen_visit_alternate(name, variants)) |