diff options
Diffstat (limited to 'scripts/qapi')
| -rw-r--r-- | scripts/qapi/commands.py | 2 | ||||
| -rw-r--r-- | scripts/qapi/events.py | 2 | ||||
| -rw-r--r-- | scripts/qapi/gen.py | 2 | ||||
| -rw-r--r-- | scripts/qapi/schema.py | 48 | ||||
| -rw-r--r-- | scripts/qapi/types.py | 2 | ||||
| -rw-r--r-- | scripts/qapi/visit.py | 17 |
6 files changed, 67 insertions, 6 deletions
diff --git a/scripts/qapi/commands.py b/scripts/qapi/commands.py index cf68aaf0bf..79c5e5c3a9 100644 --- a/scripts/qapi/commands.py +++ b/scripts/qapi/commands.py @@ -64,7 +64,7 @@ def gen_call(name: str, elif arg_type: assert not arg_type.variants for memb in arg_type.members: - if memb.optional: + if memb.need_has(): argstr += 'arg.has_%s, ' % c_name(memb.name) argstr += 'arg.%s, ' % c_name(memb.name) diff --git a/scripts/qapi/events.py b/scripts/qapi/events.py index e762d53d19..3cf01e96b6 100644 --- a/scripts/qapi/events.py +++ b/scripts/qapi/events.py @@ -60,7 +60,7 @@ def gen_param_var(typ: QAPISchemaObjectType) -> str: for memb in typ.members: ret += sep sep = ', ' - if memb.optional: + if memb.need_has(): ret += 'has_' + c_name(memb.name) + sep if memb.type.name == 'str': # Cast away const added in build_params() diff --git a/scripts/qapi/gen.py b/scripts/qapi/gen.py index 113b49134d..b5a8d03e8e 100644 --- a/scripts/qapi/gen.py +++ b/scripts/qapi/gen.py @@ -121,7 +121,7 @@ def build_params(arg_type: Optional[QAPISchemaObjectType], for memb in arg_type.members: ret += sep sep = ', ' - if memb.optional: + if memb.need_has(): ret += 'bool has_%s, ' % c_name(memb.name) ret += '%s %s' % (memb.type.c_param_type(), c_name(memb.name)) diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index 3728340c37..58b00982ea 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -253,6 +253,11 @@ class QAPISchemaType(QAPISchemaEntity): return None return self.name + def need_has_if_optional(self): + # When FOO is a pointer, has_FOO == !!FOO, i.e. has_FOO is redundant. + # Except for arrays; see QAPISchemaArrayType.need_has_if_optional(). + return not self.c_type().endswith(POINTER_SUFFIX) + def check(self, schema): QAPISchemaEntity.check(self, schema) for feat in self.features: @@ -352,6 +357,11 @@ class QAPISchemaArrayType(QAPISchemaType): self._element_type_name = element_type self.element_type = None + def need_has_if_optional(self): + # When FOO is an array, we still need has_FOO to distinguish + # absent (!has_FOO) from present and empty (has_FOO && !FOO). + return True + def check(self, schema): super().check(schema) self.element_type = schema.resolve_type( @@ -745,6 +755,44 @@ class QAPISchemaObjectTypeMember(QAPISchemaMember): self.optional = optional self.features = features or [] + def need_has(self): + assert self.type + # Temporary hack to support dropping the has_FOO in reviewable chunks + opt_out = [ + 'qapi/acpi.json', + 'qapi/audio.json', + 'qapi/block-core.json', + 'qapi/block-export.json', + 'qapi/block.json', + 'qapi/char.json', + 'qapi/crypto.json', + 'qapi/dump.json', + 'qapi/introspect.json', + 'qapi/job.json', + 'qapi/machine.json', + 'qapi/machine-target.json', + 'qapi/migration.json', + 'qapi/misc.json', + 'qapi/net.json', + 'qapi/pci.json', + 'qapi/qdev.json', + 'qapi/qom.json', + 'qapi/replay.json', + 'qapi/rocker.json', + 'qapi/run-state.json', + 'qapi/stats.json', + 'qapi/tpm.json', + 'qapi/transaction.json', + 'qapi/ui.json', + 'qapi/virtio.json', + 'qga/qapi-schema.json', + 'tests/qapi-schema/qapi-schema-test.json'] + if self.info and any(self.info.fname.endswith(mod) + for mod in opt_out): + return self.optional + # End of temporary hack + return self.optional and self.type.need_has_if_optional() + def check(self, schema): assert self.defined_in self.type = schema.resolve_type(self._type_name, self.info, diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py index 477d027001..c39d054d2c 100644 --- a/scripts/qapi/types.py +++ b/scripts/qapi/types.py @@ -142,7 +142,7 @@ def gen_struct_members(members: List[QAPISchemaObjectTypeMember]) -> str: ret = '' for memb in members: ret += memb.ifcond.gen_if() - if memb.optional: + if memb.need_has(): ret += mcgen(''' bool has_%(c_name)s; ''', diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py index 380fa197f5..26a584ee4c 100644 --- a/scripts/qapi/visit.py +++ b/scripts/qapi/visit.py @@ -71,6 +71,16 @@ bool visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp) ''', c_name=c_name(name)) + sep = '' + for memb in members: + if memb.optional and not memb.need_has(): + ret += mcgen(''' + bool has_%(c_name)s = !!obj->%(c_name)s; +''', + c_name=c_name(memb.name)) + sep = '\n' + ret += sep + if base: ret += mcgen(''' if (!visit_type_%(c_type)s_members(v, (%(c_type)s *)obj, errp)) { @@ -82,10 +92,13 @@ bool visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp) for memb in members: ret += memb.ifcond.gen_if() if memb.optional: + has = 'has_' + c_name(memb.name) + if memb.need_has(): + has = 'obj->' + has ret += mcgen(''' - if (visit_optional(v, "%(name)s", &obj->has_%(c_name)s)) { + if (visit_optional(v, "%(name)s", &%(has)s)) { ''', - name=memb.name, c_name=c_name(memb.name)) + name=memb.name, has=has) indent.increase() special_features = gen_special_features(memb.features) if special_features != '0': |