...
...
12
I've changed impl such that we expose all features to the code
12
I've changed impl such that we expose all features to the code
13
regardless of whether they are special, and don't require any pragma.
13
regardless of whether they are special, and don't require any pragma.
14
14
15
I've split it from the QGA patches since it makes more sense to work
15
I've split it from the QGA patches since it makes more sense to work
16
on this bit in isolation.
16
on this bit in isolation.
17
18
Changed in v4:
19
20
* Apply fixes to make mypy happy
17
21
18
Changed in v3:
22
Changed in v3:
19
23
20
* "make -C python check-tox" is now clean
24
* "make -C python check-tox" is now clean
21
* Added test case for "too many features" error scenario
25
* Added test case for "too many features" error scenario
...
...
58
qapi/qobject-output-visitor.c | 6 +--
62
qapi/qobject-output-visitor.c | 6 +--
59
scripts/qapi/commands.py | 5 ++-
63
scripts/qapi/commands.py | 5 ++-
60
scripts/qapi/features.py | 51 ++++++++++++++++++++++++
64
scripts/qapi/features.py | 51 ++++++++++++++++++++++++
61
scripts/qapi/gen.py | 9 +++--
65
scripts/qapi/gen.py | 9 +++--
62
scripts/qapi/main.py | 2 +
66
scripts/qapi/main.py | 2 +
63
scripts/qapi/schema.py | 30 +++++++++++++-
67
scripts/qapi/schema.py | 31 +++++++++++++-
64
scripts/qapi/types.py | 19 +++++----
68
scripts/qapi/types.py | 19 +++++----
65
scripts/qapi/visit.py | 17 ++++----
69
scripts/qapi/visit.py | 17 ++++----
66
tests/meson.build | 2 +
70
tests/meson.build | 2 +
67
tests/qapi-schema/features-too-many.err | 2 +
71
tests/qapi-schema/features-too-many.err | 2 +
68
tests/qapi-schema/features-too-many.json | 13 ++++++
72
tests/qapi-schema/features-too-many.json | 13 ++++++
69
tests/qapi-schema/features-too-many.out | 0
73
tests/qapi-schema/features-too-many.out | 0
70
tests/qapi-schema/meson.build | 1 +
74
tests/qapi-schema/meson.build | 1 +
71
25 files changed, 162 insertions(+), 56 deletions(-)
75
25 files changed, 163 insertions(+), 56 deletions(-)
72
create mode 100644 scripts/qapi/features.py
76
create mode 100644 scripts/qapi/features.py
73
create mode 100644 tests/qapi-schema/features-too-many.err
77
create mode 100644 tests/qapi-schema/features-too-many.err
74
create mode 100644 tests/qapi-schema/features-too-many.json
78
create mode 100644 tests/qapi-schema/features-too-many.json
75
create mode 100644 tests/qapi-schema/features-too-many.out
79
create mode 100644 tests/qapi-schema/features-too-many.out
76
80
77
--
81
--
78
2.46.0
82
2.47.1
79
83
80
84
diff view generated by jsdifflib
...
...
26
+ special_features = [f"1u << {c_enum_const('qapi', feat.name)}"
26
+ special_features = [f"1u << {c_enum_const('qapi', feat.name)}"
27
for feat in features if feat.is_special()]
27
for feat in features if feat.is_special()]
28
return ' | '.join(special_features) or '0'
28
return ' | '.join(special_features) or '0'
29
29
30
--
30
--
31
2.46.0
31
2.47.1
32
32
33
33
diff view generated by jsdifflib
...
...
318
+ .features = (const uint64_t[%(max_index)s]) {
318
+ .features = (const uint64_t[%(max_index)s]) {
319
''',
319
''',
320
max_index=max_index)
320
max_index=max_index)
321
ret += feats
321
ret += feats
322
--
322
--
323
2.46.0
323
2.47.1
324
324
325
325
diff view generated by jsdifflib
...
...
122
+ if features != '0':
122
+ if features != '0':
123
indent.decrease()
123
indent.decrease()
124
ret += mcgen('''
124
ret += mcgen('''
125
}
125
}
126
--
126
--
127
2.46.0
127
2.47.1
128
128
129
129
diff view generated by jsdifflib
...
...
13
meson.build | 1 +
13
meson.build | 1 +
14
scripts/qapi/commands.py | 1 +
14
scripts/qapi/commands.py | 1 +
15
scripts/qapi/features.py | 51 ++++++++++++++++++++++++
15
scripts/qapi/features.py | 51 ++++++++++++++++++++++++
16
scripts/qapi/gen.py | 6 +--
16
scripts/qapi/gen.py | 6 +--
17
scripts/qapi/main.py | 2 +
17
scripts/qapi/main.py | 2 +
18
scripts/qapi/schema.py | 30 +++++++++++++-
18
scripts/qapi/schema.py | 31 +++++++++++++-
19
scripts/qapi/types.py | 7 +++-
19
scripts/qapi/types.py | 7 +++-
20
scripts/qapi/visit.py | 3 +-
20
scripts/qapi/visit.py | 3 +-
21
tests/meson.build | 2 +
21
tests/meson.build | 2 +
22
tests/qapi-schema/features-too-many.err | 2 +
22
tests/qapi-schema/features-too-many.err | 2 +
23
tests/qapi-schema/features-too-many.json | 13 ++++++
23
tests/qapi-schema/features-too-many.json | 13 ++++++
24
tests/qapi-schema/features-too-many.out | 0
24
tests/qapi-schema/features-too-many.out | 0
25
tests/qapi-schema/meson.build | 1 +
25
tests/qapi-schema/meson.build | 1 +
26
13 files changed, 112 insertions(+), 7 deletions(-)
26
13 files changed, 113 insertions(+), 7 deletions(-)
27
create mode 100644 scripts/qapi/features.py
27
create mode 100644 scripts/qapi/features.py
28
create mode 100644 tests/qapi-schema/features-too-many.err
28
create mode 100644 tests/qapi-schema/features-too-many.err
29
create mode 100644 tests/qapi-schema/features-too-many.json
29
create mode 100644 tests/qapi-schema/features-too-many.json
30
create mode 100644 tests/qapi-schema/features-too-many.out
30
create mode 100644 tests/qapi-schema/features-too-many.out
31
31
...
...
66
+
66
+
67
+This work is licensed under the terms of the GNU GPL, version 2.
67
+This work is licensed under the terms of the GNU GPL, version 2.
68
+# See the COPYING file in the top-level directory.
68
+# See the COPYING file in the top-level directory.
69
+"""
69
+"""
70
+
70
+
71
+from typing import Dict
71
+from typing import Dict, ValuesView
72
+
72
+
73
+from .common import c_enum_const, c_name
73
+from .common import c_enum_const, c_name
74
+from .gen import QAPISchemaMonolithicCVisitor
74
+from .gen import QAPISchemaMonolithicCVisitor
75
+from .schema import (
75
+from .schema import (
76
+ QAPISchema,
76
+ QAPISchema,
...
...
84
+ super().__init__(
84
+ super().__init__(
85
+ prefix, 'qapi-features',
85
+ prefix, 'qapi-features',
86
+ ' * Schema-defined QAPI features',
86
+ ' * Schema-defined QAPI features',
87
+ __doc__)
87
+ __doc__)
88
+
88
+
89
+ self.features: Dict[str, QAPISchemaFeature] = {}
89
+ self.features: ValuesView[QAPISchemaFeature]
90
+
90
+
91
+ def visit_begin(self, schema: QAPISchema) -> None:
91
+ def visit_begin(self, schema: QAPISchema) -> None:
92
+ self.features = schema.features()
92
+ self.features = schema.features()
93
+ self._genh.add("#include \"qapi/util.h\"\n\n")
93
+ self._genh.add("#include \"qapi/util.h\"\n\n")
94
+
94
+
...
...
149
gen_events(schema, output_dir, prefix)
149
gen_events(schema, output_dir, prefix)
150
diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py
150
diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py
151
index XXXXXXX..XXXXXXX 100644
151
index XXXXXXX..XXXXXXX 100644
152
--- a/scripts/qapi/schema.py
152
--- a/scripts/qapi/schema.py
153
+++ b/scripts/qapi/schema.py
153
+++ b/scripts/qapi/schema.py
154
@@ -XXX,XX +XXX,XX @@
155
List,
156
Optional,
157
Union,
158
+ ValuesView,
159
cast,
160
)
161
154
@@ -XXX,XX +XXX,XX @@ def connect_doc(self, doc: Optional[QAPIDoc]) -> None:
162
@@ -XXX,XX +XXX,XX @@ def connect_doc(self, doc: Optional[QAPIDoc]) -> None:
155
class QAPISchemaFeature(QAPISchemaMember):
163
class QAPISchemaFeature(QAPISchemaMember):
156
role = 'feature'
164
role = 'feature'
157
165
158
+ # Features which are standardized across all schemas
166
+ # Features which are standardized across all schemas
...
...
167
@@ -XXX,XX +XXX,XX @@ def __init__(self, fname: str):
175
@@ -XXX,XX +XXX,XX @@ def __init__(self, fname: str):
168
self._entity_list: List[QAPISchemaEntity] = []
176
self._entity_list: List[QAPISchemaEntity] = []
169
self._entity_dict: Dict[str, QAPISchemaDefinition] = {}
177
self._entity_dict: Dict[str, QAPISchemaDefinition] = {}
170
self._module_dict: Dict[str, QAPISchemaModule] = OrderedDict()
178
self._module_dict: Dict[str, QAPISchemaModule] = OrderedDict()
171
+ # NB, values in the dict will identify the first encountered
179
+ # NB, values in the dict will identify the first encountered
172
+ # usage of a named feature only
180
+ # usage of a named feature only
173
+ self._feature_dict: Dict[str, QAPISchemaFeature] = OrderedDict()
181
+ self._feature_dict: Dict[str, QAPISchemaFeature] = OrderedDict()
174
+
182
+
175
+ # All schemas get the names defined in the QapiSpecialFeature enum.
183
+ # All schemas get the names defined in the QapiSpecialFeature enum.
176
+ # Use of OrderedDict ensures they are emitted first when generating
184
+ # Rely on dict iteration order matching insertion order so that
177
+ # the enum definition, thus matching QapiSpecialFeature.
185
+ # the special names are emitted first when generating code.
178
+ for f in QAPISchemaFeature.SPECIAL_NAMES:
186
+ for f in QAPISchemaFeature.SPECIAL_NAMES:
179
+ self._feature_dict[f] = QAPISchemaFeature(f, None)
187
+ self._feature_dict[f] = QAPISchemaFeature(f, None)
180
+
188
+
181
self._schema_dir = os.path.dirname(fname)
189
self._schema_dir = os.path.dirname(fname)
182
self._make_module(QAPISchemaModule.BUILTIN_MODULE_NAME)
190
self._make_module(QAPISchemaModule.BUILTIN_MODULE_NAME)
183
self._make_module(fname)
191
self._make_module(fname)
184
@@ -XXX,XX +XXX,XX @@ def __init__(self, fname: str):
192
@@ -XXX,XX +XXX,XX @@ def __init__(self, fname: str):
185
self._def_exprs(exprs)
193
self._def_exprs(exprs)
186
self.check()
194
self.check()
187
195
188
+ def features(self) -> List[QAPISchemaFeature]:
196
+ def features(self) -> ValuesView[QAPISchemaFeature]:
189
+ return self._feature_dict.values()
197
+ return self._feature_dict.values()
190
+
198
+
191
def _def_entity(self, ent: QAPISchemaEntity) -> None:
199
def _def_entity(self, ent: QAPISchemaEntity) -> None:
192
self._entity_list.append(ent)
200
self._entity_list.append(ent)
193
201
...
...
307
+ 'features-too-many.json',
315
+ 'features-too-many.json',
308
'features-bad-type.json',
316
'features-bad-type.json',
309
'features-deprecated-type.json',
317
'features-deprecated-type.json',
310
'features-duplicate-name.json',
318
'features-duplicate-name.json',
311
--
319
--
312
2.46.0
320
2.47.1
313
321
314
322
diff view generated by jsdifflib