aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/devel/qapi-code-gen.rst16
-rw-r--r--qapi/compat.json2
-rw-r--r--qapi/introspect.json5
-rw-r--r--scripts/qapi/expr.py3
-rw-r--r--scripts/qapi/introspect.py5
-rw-r--r--scripts/qapi/schema.py22
-rw-r--r--tests/qapi-schema/doc-good.json5
-rw-r--r--tests/qapi-schema/doc-good.out3
-rw-r--r--tests/qapi-schema/doc-good.txt3
-rw-r--r--tests/qapi-schema/enum-dict-member-unknown.err2
-rw-r--r--tests/qapi-schema/qapi-schema-test.json3
-rw-r--r--tests/qapi-schema/qapi-schema-test.out1
-rwxr-xr-xtests/qapi-schema/test-qapi.py1
13 files changed, 57 insertions, 14 deletions
diff --git a/docs/devel/qapi-code-gen.rst b/docs/devel/qapi-code-gen.rst
index d267889..4071c90 100644
--- a/docs/devel/qapi-code-gen.rst
+++ b/docs/devel/qapi-code-gen.rst
@@ -200,7 +200,9 @@ Syntax::
'*if': COND,
'*features': FEATURES }
ENUM-VALUE = STRING
- | { 'name': STRING, '*if': COND }
+ | { 'name': STRING,
+ '*if': COND,
+ '*features': FEATURES }
Member 'enum' names the enum type.
@@ -706,8 +708,10 @@ QEMU shows a certain behaviour.
Special features
~~~~~~~~~~~~~~~~
-Feature "deprecated" marks a command, event, or struct member as
-deprecated. It is not supported elsewhere so far.
+Feature "deprecated" marks a command, event, enum value, or struct
+member as deprecated. It is not supported elsewhere so far.
+Interfaces so marked may be withdrawn in future releases in accordance
+with QEMU's deprecation policy.
Naming rules and reserved names
@@ -1157,7 +1161,8 @@ and "variants".
"members" is a JSON array describing the object's common members, if
any. Each element is a JSON object with members "name" (the member's
-name), "type" (the name of its type), and optionally "default". The
+name), "type" (the name of its type), "features" (a JSON array of
+feature strings), and "default". The latter two are optional. The
member is optional if "default" is present. Currently, "default" can
only have value null. Other values are reserved for future
extensions. The "members" array is in no particular order; clients
@@ -1234,7 +1239,8 @@ The SchemaInfo for an enumeration type has meta-type "enum" and
variant member "members".
"members" is a JSON array describing the enumeration values. Each
-element is a JSON object with member "name" (the member's name). The
+element is a JSON object with member "name" (the member's name), and
+optionally "features" (a JSON array of feature strings). The
"members" array is in no particular order; clients must search the
entire array when learning whether a particular value is supported.
diff --git a/qapi/compat.json b/qapi/compat.json
index ae3afc2..1d2b76f 100644
--- a/qapi/compat.json
+++ b/qapi/compat.json
@@ -42,6 +42,8 @@
# with feature 'deprecated'. We may want to extend it to cover
# semantic aspects, CLI, and experimental features.
#
+# Limitation: not implemented for deprecated enumeration values.
+#
# @deprecated-input: how to handle deprecated input (default 'accept')
# @deprecated-output: how to handle deprecated output (default 'accept')
#
diff --git a/qapi/introspect.json b/qapi/introspect.json
index 9683e88..183148b 100644
--- a/qapi/introspect.json
+++ b/qapi/introspect.json
@@ -167,10 +167,13 @@
#
# @name: the member's name, as defined in the QAPI schema.
#
+# @features: names of features associated with the member, in no
+# particular order.
+#
# Since: 6.2
##
{ 'struct': 'SchemaInfoEnumMember',
- 'data': { 'name': 'str' } }
+ 'data': { 'name': 'str', '*features': [ 'str' ] } }
##
# @SchemaInfoArray:
diff --git a/scripts/qapi/expr.py b/scripts/qapi/expr.py
index 819ea6a..3cb389e 100644
--- a/scripts/qapi/expr.py
+++ b/scripts/qapi/expr.py
@@ -472,7 +472,7 @@ def check_enum(expr: _JSONObject, info: QAPISourceInfo) -> None:
for m in members]
for member in members:
source = "'data' member"
- check_keys(member, info, source, ['name'], ['if'])
+ check_keys(member, info, source, ['name'], ['if', 'features'])
member_name = member['name']
check_name_is_str(member_name, info, source)
source = "%s '%s'" % (source, member_name)
@@ -483,6 +483,7 @@ def check_enum(expr: _JSONObject, info: QAPISourceInfo) -> None:
permit_upper=permissive,
permit_underscore=permissive)
check_if(member, info, source)
+ check_features(member.get('features'), info)
def check_struct(expr: _JSONObject, info: QAPISourceInfo) -> None:
diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py
index 6334546..67c7d89 100644
--- a/scripts/qapi/introspect.py
+++ b/scripts/qapi/introspect.py
@@ -275,12 +275,13 @@ const QLitObject %(c_name)s = %(c_string)s;
obj['features'] = self._gen_features(features)
self._trees.append(Annotated(obj, ifcond, comment))
- @staticmethod
- def _gen_enum_member(member: QAPISchemaEnumMember
+ def _gen_enum_member(self, member: QAPISchemaEnumMember
) -> Annotated[SchemaInfoEnumMember]:
obj: SchemaInfoEnumMember = {
'name': member.name,
}
+ if member.features:
+ obj['features'] = self._gen_features(member.features)
return Annotated(obj, member.ifcond)
def _gen_object_member(self, member: QAPISchemaObjectTypeMember
diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py
index 004d709..6d5f465 100644
--- a/scripts/qapi/schema.py
+++ b/scripts/qapi/schema.py
@@ -708,6 +708,19 @@ class QAPISchemaMember:
class QAPISchemaEnumMember(QAPISchemaMember):
role = 'value'
+ def __init__(self, name, info, ifcond=None, features=None):
+ super().__init__(name, info, ifcond)
+ for f in features or []:
+ assert isinstance(f, QAPISchemaFeature)
+ f.set_defined_in(name)
+ self.features = features or []
+
+ def connect_doc(self, doc):
+ super().connect_doc(doc)
+ if doc:
+ for f in self.features:
+ doc.connect_feature(f)
+
class QAPISchemaFeature(QAPISchemaMember):
role = 'feature'
@@ -980,9 +993,14 @@ class QAPISchema:
QAPISchemaIfCond(f.get('if')))
for f in features]
+ def _make_enum_member(self, name, ifcond, features, info):
+ return QAPISchemaEnumMember(name, info,
+ QAPISchemaIfCond(ifcond),
+ self._make_features(features, info))
+
def _make_enum_members(self, values, info):
- return [QAPISchemaEnumMember(v['name'], info,
- QAPISchemaIfCond(v.get('if')))
+ return [self._make_enum_member(v['name'], v.get('if'),
+ v.get('features'), info)
for v in values]
def _make_array_type(self, element_type, info):
diff --git a/tests/qapi-schema/doc-good.json b/tests/qapi-schema/doc-good.json
index 86dc25d..74745fb 100644
--- a/tests/qapi-schema/doc-good.json
+++ b/tests/qapi-schema/doc-good.json
@@ -58,11 +58,14 @@
#
# Features:
# @enum-feat: Also _one_ {and only}
+# @enum-member-feat: a member feature
#
# @two is undocumented
##
{ 'enum': 'Enum',
- 'data': [ { 'name': 'one', 'if': 'IFONE' }, 'two' ],
+ 'data': [ { 'name': 'one', 'if': 'IFONE',
+ 'features': [ 'enum-member-feat' ] },
+ 'two' ],
'features': [ 'enum-feat' ],
'if': 'IFCOND' }
diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out
index 5a324e2..9dd65b9 100644
--- a/tests/qapi-schema/doc-good.out
+++ b/tests/qapi-schema/doc-good.out
@@ -13,6 +13,7 @@ module doc-good.json
enum Enum
member one
if IFONE
+ feature enum-member-feat
member two
if IFCOND
feature enum-feat
@@ -108,6 +109,8 @@ The _one_ {and only}
feature=enum-feat
Also _one_ {and only}
+ feature=enum-member-feat
+a member feature
section=None
@two is undocumented
doc symbol=Base
diff --git a/tests/qapi-schema/doc-good.txt b/tests/qapi-schema/doc-good.txt
index 701402e..b3b76bd 100644
--- a/tests/qapi-schema/doc-good.txt
+++ b/tests/qapi-schema/doc-good.txt
@@ -56,6 +56,9 @@ Features
"enum-feat"
Also _one_ {and only}
+"enum-member-feat"
+ a member feature
+
"two" is undocumented
diff --git a/tests/qapi-schema/enum-dict-member-unknown.err b/tests/qapi-schema/enum-dict-member-unknown.err
index f8617ea..235cde0 100644
--- a/tests/qapi-schema/enum-dict-member-unknown.err
+++ b/tests/qapi-schema/enum-dict-member-unknown.err
@@ -1,3 +1,3 @@
enum-dict-member-unknown.json: In enum 'MyEnum':
enum-dict-member-unknown.json:2: 'data' member has unknown key 'bad-key'
-Valid keys are 'if', 'name'.
+Valid keys are 'features', 'if', 'name'.
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index 2ec5010..b677ab8 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -301,7 +301,8 @@
'TEST_IF_COND_2'] } } ] }
{ 'enum': 'FeatureEnum1',
- 'data': [ 'eins', 'zwei', 'drei' ],
+ 'data': [ 'eins', 'zwei',
+ { 'name': 'drei', 'features': [ 'deprecated' ] } ],
'features': [ 'feature1' ] }
{ 'union': 'FeatureUnion1',
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index 9337adc..16846db 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -341,6 +341,7 @@ enum FeatureEnum1
member eins
member zwei
member drei
+ feature deprecated
feature feature1
object q_obj_FeatureUnion1-base
member tag: FeatureEnum1 optional=False
diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
index c717a7a..2160cef 100755
--- a/tests/qapi-schema/test-qapi.py
+++ b/tests/qapi-schema/test-qapi.py
@@ -37,6 +37,7 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
for m in members:
print(' member %s' % m.name)
self._print_if(m.ifcond, indent=8)
+ self._print_features(m.features, indent=8)
self._print_if(ifcond)
self._print_features(features)