... | ... | ||
---|---|---|---|
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 |