qapi: make 'if' condition strings simple identifiers

Change the 'if' condition strings to be C-agnostic. It will accept
'[A-Z][A-Z0-9_]*' identifiers. This allows to express configuration
conditions in other languages (Rust or Python for ex) or other more
suitable forms.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Tested-by: John Snow <jsnow@redhat.com>
Message-Id: <20210804083105.97531-11-marcandre.lureau@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
[Rebased with semantic conflict in redefined-event.json]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
This commit is contained in:
Marc-André Lureau 2021-08-04 12:31:05 +04:00 committed by Markus Armbruster
parent 2b7d214536
commit 8a9f1e1d9c
25 changed files with 206 additions and 208 deletions

View file

@ -1,2 +1,2 @@
alternate-branch-if-invalid.json: In alternate 'Alt':
alternate-branch-if-invalid.json:2: 'if' condition ' ' of 'data' member 'branch' makes no sense
alternate-branch-if-invalid.json:2: 'if' condition ' ' of 'data' member 'branch' is not a valid identifier

View file

@ -1,2 +1,2 @@
bad-if-empty.json: In struct 'TestIfStruct':
bad-if-empty.json:2: 'if' condition '' of struct makes no sense
bad-if-empty.json:2: 'if' condition '' of struct is not a valid identifier

View file

@ -1,2 +1,2 @@
bad-if-list.json: In struct 'TestIfStruct':
bad-if-list.json:2: 'if' condition ' ' of struct makes no sense
bad-if-list.json:2: 'if' condition 'foo' of struct is not a valid identifier

View file

@ -1,3 +1,3 @@
# check invalid 'if' type
{ 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
'if': ['defined(TEST_IF_STRUCT)'] }
'if': ['TEST_IF_STRUCT'] }

View file

@ -61,9 +61,9 @@
# @two is undocumented
##
{ 'enum': 'Enum', 'data':
[ { 'name': 'one', 'if': 'defined(IFONE)' }, 'two' ],
[ { 'name': 'one', 'if': 'IFONE' }, 'two' ],
'features': [ 'enum-feat' ],
'if': 'defined(IFCOND)' }
'if': 'IFCOND' }
##
# @Base:
@ -87,7 +87,7 @@
'features': [ 'variant1-feat' ],
'data': { 'var1': { 'type': 'str',
'features': [ 'member-feat' ],
'if': 'defined(IFSTR)' } } }
'if': 'IFSTR' } } }
##
# @Variant2:

View file

@ -12,16 +12,16 @@ enum QType
module doc-good.json
enum Enum
member one
if defined(IFONE)
if IFONE
member two
if defined(IFCOND)
if IFCOND
feature enum-feat
object Base
member base1: Enum optional=False
if OrderedDict([('all', ['IFALL1', 'IFALL2'])])
object Variant1
member var1: str optional=False
if defined(IFSTR)
if IFSTR
feature member-feat
feature variant1-feat
object Variant2

View file

@ -43,7 +43,7 @@ Example:
Values
~~~~~~
"one" (**If: **"defined(IFONE)")
"one" (**If: **"IFONE")
The _one_ {and only}
"two"
@ -62,7 +62,7 @@ Features
If
~~
"defined(IFCOND)"
"IFCOND"
"Base" (Object)
@ -93,7 +93,7 @@ Another paragraph (but no "var": line)
Members
~~~~~~~
"var1": "string" (**If: **"defined(IFSTR)")
"var1": "string" (**If: **"IFSTR")
Not documented

View file

@ -1,3 +1,3 @@
{ 'struct': 'FeatureStruct0',
'data': { 'foo': 'int' },
'features': [ { 'if': 'defined(NAMELESS_FEATURES)' } ] }
'features': [ { 'if': 'NAMELESS_FEATURES' } ] }

View file

@ -222,45 +222,45 @@
{ 'struct': 'TestIfStruct', 'data':
{ 'foo': 'int',
'bar': { 'type': 'int', 'if': 'defined(TEST_IF_STRUCT_BAR)'} },
'if': 'defined(TEST_IF_STRUCT)' }
'bar': { 'type': 'int', 'if': 'TEST_IF_STRUCT_BAR'} },
'if': 'TEST_IF_STRUCT' }
{ 'enum': 'TestIfEnum', 'data':
[ 'foo', { 'name' : 'bar', 'if': 'defined(TEST_IF_ENUM_BAR)' } ],
'if': 'defined(TEST_IF_ENUM)' }
[ 'foo', { 'name' : 'bar', 'if': 'TEST_IF_ENUM_BAR' } ],
'if': 'TEST_IF_ENUM' }
{ 'union': 'TestIfUnion', 'data':
{ 'foo': 'TestStruct',
'bar': { 'type': 'str', 'if': 'defined(TEST_IF_UNION_BAR)'} },
'if': { 'all': ['defined(TEST_IF_UNION)', 'defined(TEST_IF_STRUCT)'] } }
'bar': { 'type': 'str', 'if': 'TEST_IF_UNION_BAR'} },
'if': { 'all': ['TEST_IF_UNION', 'TEST_IF_STRUCT'] } }
{ 'command': 'test-if-union-cmd',
'data': { 'union-cmd-arg': 'TestIfUnion' },
'if': 'defined(TEST_IF_UNION)' }
'if': 'TEST_IF_UNION' }
{ 'alternate': 'TestIfAlternate', 'data':
{ 'foo': 'int',
'bar': { 'type': 'TestStruct', 'if': 'defined(TEST_IF_ALT_BAR)'} },
'if': { 'all': ['defined(TEST_IF_ALT)', 'defined(TEST_IF_STRUCT)'] } }
'bar': { 'type': 'TestStruct', 'if': 'TEST_IF_ALT_BAR'} },
'if': { 'all': ['TEST_IF_ALT', 'TEST_IF_STRUCT'] } }
{ 'command': 'test-if-alternate-cmd',
'data': { 'alt-cmd-arg': 'TestIfAlternate' },
'if': { 'all': ['defined(TEST_IF_ALT)',
{'not': 'defined(TEST_IF_NOT_ALT)'}] } }
'if': { 'all': ['TEST_IF_ALT',
{'not': 'TEST_IF_NOT_ALT'}] } }
{ 'command': 'test-if-cmd',
'data': {
'foo': 'TestIfStruct',
'bar': { 'type': 'TestIfEnum', 'if': 'defined(TEST_IF_CMD_BAR)' } },
'bar': { 'type': 'TestIfEnum', 'if': 'TEST_IF_CMD_BAR' } },
'returns': 'UserDefThree',
'if': { 'all': ['defined(TEST_IF_CMD)', 'defined(TEST_IF_STRUCT)'] } }
'if': { 'all': ['TEST_IF_CMD', 'TEST_IF_STRUCT'] } }
{ 'command': 'test-cmd-return-def-three', 'returns': 'UserDefThree' }
{ 'event': 'TEST_IF_EVENT', 'data':
{ 'foo': 'TestIfStruct',
'bar': { 'type': ['TestIfEnum'], 'if': 'defined(TEST_IF_EVT_BAR)' } },
'if': { 'all': ['defined(TEST_IF_EVT)', 'defined(TEST_IF_STRUCT)'] } }
'bar': { 'type': ['TestIfEnum'], 'if': 'TEST_IF_EVT_BAR' } },
'if': { 'all': ['TEST_IF_EVT', 'TEST_IF_STRUCT'] } }
# test 'features'
@ -282,21 +282,21 @@
{ 'struct': 'CondFeatureStruct1',
'data': { 'foo': 'int' },
'features': [ { 'name': 'feature1', 'if': 'defined(TEST_IF_FEATURE_1)'} ] }
'features': [ { 'name': 'feature1', 'if': 'TEST_IF_FEATURE_1'} ] }
{ 'struct': 'CondFeatureStruct2',
'data': { 'foo': 'int' },
'features': [ { 'name': 'feature1', 'if': 'defined(TEST_IF_FEATURE_1)'},
{ 'name': 'feature2', 'if': 'defined(TEST_IF_FEATURE_2)'} ] }
'features': [ { 'name': 'feature1', 'if': 'TEST_IF_FEATURE_1'},
{ 'name': 'feature2', 'if': 'TEST_IF_FEATURE_2'} ] }
{ 'struct': 'CondFeatureStruct3',
'data': { 'foo': 'int' },
'features': [ { 'name': 'feature1',
'if': { 'all': [ 'defined(TEST_IF_COND_1)',
'defined(TEST_IF_COND_2)'] } } ] }
'if': { 'all': [ 'TEST_IF_COND_1',
'TEST_IF_COND_2'] } } ] }
{ 'struct': 'CondFeatureStruct4',
'data': { 'foo': 'int' },
'features': [ { 'name': 'feature1',
'if': {'any': ['defined(TEST_IF_COND_1)',
'defined(TEST_IF_COND_2)'] } } ] }
'if': {'any': ['TEST_IF_COND_1',
'TEST_IF_COND_2'] } } ] }
{ 'enum': 'FeatureEnum1',
'data': [ 'eins', 'zwei', 'drei' ],
@ -331,14 +331,14 @@
'features': [ 'feature1', 'feature2' ] }
{ 'command': 'test-command-cond-features1',
'features': [ { 'name': 'feature1', 'if': 'defined(TEST_IF_FEATURE_1)'} ] }
'features': [ { 'name': 'feature1', 'if': 'TEST_IF_FEATURE_1'} ] }
{ 'command': 'test-command-cond-features2',
'features': [ { 'name': 'feature1', 'if': 'defined(TEST_IF_FEATURE_1)'},
{ 'name': 'feature2', 'if': 'defined(TEST_IF_FEATURE_2)'} ] }
'features': [ { 'name': 'feature1', 'if': 'TEST_IF_FEATURE_1'},
{ 'name': 'feature2', 'if': 'TEST_IF_FEATURE_2'} ] }
{ 'command': 'test-command-cond-features3',
'features': [ { 'name': 'feature1',
'if': { 'all': [ 'defined(TEST_IF_COND_1)',
'defined(TEST_IF_COND_2)'] } } ] }
'if': { 'all': [ 'TEST_IF_COND_1',
'TEST_IF_COND_2'] } } ] }
{ 'event': 'TEST_EVENT_FEATURES0',
'data': 'FeatureStruct1' }

View file

@ -298,65 +298,65 @@ command __org.qemu_x-command q_obj___org.qemu_x-command-arg -> __org.qemu_x-Unio
object TestIfStruct
member foo: int optional=False
member bar: int optional=False
if defined(TEST_IF_STRUCT_BAR)
if defined(TEST_IF_STRUCT)
if TEST_IF_STRUCT_BAR
if TEST_IF_STRUCT
enum TestIfEnum
member foo
member bar
if defined(TEST_IF_ENUM_BAR)
if defined(TEST_IF_ENUM)
if TEST_IF_ENUM_BAR
if TEST_IF_ENUM
object q_obj_TestStruct-wrapper
member data: TestStruct optional=False
enum TestIfUnionKind
member foo
member bar
if defined(TEST_IF_UNION_BAR)
if OrderedDict([('all', ['defined(TEST_IF_UNION)', 'defined(TEST_IF_STRUCT)'])])
if TEST_IF_UNION_BAR
if OrderedDict([('all', ['TEST_IF_UNION', 'TEST_IF_STRUCT'])])
object TestIfUnion
member type: TestIfUnionKind optional=False
tag type
case foo: q_obj_TestStruct-wrapper
case bar: q_obj_str-wrapper
if defined(TEST_IF_UNION_BAR)
if OrderedDict([('all', ['defined(TEST_IF_UNION)', 'defined(TEST_IF_STRUCT)'])])
if TEST_IF_UNION_BAR
if OrderedDict([('all', ['TEST_IF_UNION', 'TEST_IF_STRUCT'])])
object q_obj_test-if-union-cmd-arg
member union-cmd-arg: TestIfUnion optional=False
if defined(TEST_IF_UNION)
if TEST_IF_UNION
command test-if-union-cmd q_obj_test-if-union-cmd-arg -> None
gen=True success_response=True boxed=False oob=False preconfig=False
if defined(TEST_IF_UNION)
if TEST_IF_UNION
alternate TestIfAlternate
tag type
case foo: int
case bar: TestStruct
if defined(TEST_IF_ALT_BAR)
if OrderedDict([('all', ['defined(TEST_IF_ALT)', 'defined(TEST_IF_STRUCT)'])])
if TEST_IF_ALT_BAR
if OrderedDict([('all', ['TEST_IF_ALT', 'TEST_IF_STRUCT'])])
object q_obj_test-if-alternate-cmd-arg
member alt-cmd-arg: TestIfAlternate optional=False
if OrderedDict([('all', ['defined(TEST_IF_ALT)', OrderedDict([('not', 'defined(TEST_IF_NOT_ALT)')])])])
if OrderedDict([('all', ['TEST_IF_ALT', OrderedDict([('not', 'TEST_IF_NOT_ALT')])])])
command test-if-alternate-cmd q_obj_test-if-alternate-cmd-arg -> None
gen=True success_response=True boxed=False oob=False preconfig=False
if OrderedDict([('all', ['defined(TEST_IF_ALT)', OrderedDict([('not', 'defined(TEST_IF_NOT_ALT)')])])])
if OrderedDict([('all', ['TEST_IF_ALT', OrderedDict([('not', 'TEST_IF_NOT_ALT')])])])
object q_obj_test-if-cmd-arg
member foo: TestIfStruct optional=False
member bar: TestIfEnum optional=False
if defined(TEST_IF_CMD_BAR)
if OrderedDict([('all', ['defined(TEST_IF_CMD)', 'defined(TEST_IF_STRUCT)'])])
if TEST_IF_CMD_BAR
if OrderedDict([('all', ['TEST_IF_CMD', 'TEST_IF_STRUCT'])])
command test-if-cmd q_obj_test-if-cmd-arg -> UserDefThree
gen=True success_response=True boxed=False oob=False preconfig=False
if OrderedDict([('all', ['defined(TEST_IF_CMD)', 'defined(TEST_IF_STRUCT)'])])
if OrderedDict([('all', ['TEST_IF_CMD', 'TEST_IF_STRUCT'])])
command test-cmd-return-def-three None -> UserDefThree
gen=True success_response=True boxed=False oob=False preconfig=False
array TestIfEnumList TestIfEnum
if defined(TEST_IF_ENUM)
if TEST_IF_ENUM
object q_obj_TEST_IF_EVENT-arg
member foo: TestIfStruct optional=False
member bar: TestIfEnumList optional=False
if defined(TEST_IF_EVT_BAR)
if OrderedDict([('all', ['defined(TEST_IF_EVT)', 'defined(TEST_IF_STRUCT)'])])
if TEST_IF_EVT_BAR
if OrderedDict([('all', ['TEST_IF_EVT', 'TEST_IF_STRUCT'])])
event TEST_IF_EVENT q_obj_TEST_IF_EVENT-arg
boxed=False
if OrderedDict([('all', ['defined(TEST_IF_EVT)', 'defined(TEST_IF_STRUCT)'])])
if OrderedDict([('all', ['TEST_IF_EVT', 'TEST_IF_STRUCT'])])
object FeatureStruct0
member foo: int optional=False
object FeatureStruct1
@ -379,21 +379,21 @@ object FeatureStruct4
object CondFeatureStruct1
member foo: int optional=False
feature feature1
if defined(TEST_IF_FEATURE_1)
if TEST_IF_FEATURE_1
object CondFeatureStruct2
member foo: int optional=False
feature feature1
if defined(TEST_IF_FEATURE_1)
if TEST_IF_FEATURE_1
feature feature2
if defined(TEST_IF_FEATURE_2)
if TEST_IF_FEATURE_2
object CondFeatureStruct3
member foo: int optional=False
feature feature1
if OrderedDict([('all', ['defined(TEST_IF_COND_1)', 'defined(TEST_IF_COND_2)'])])
if OrderedDict([('all', ['TEST_IF_COND_1', 'TEST_IF_COND_2'])])
object CondFeatureStruct4
member foo: int optional=False
feature feature1
if OrderedDict([('any', ['defined(TEST_IF_COND_1)', 'defined(TEST_IF_COND_2)'])])
if OrderedDict([('any', ['TEST_IF_COND_1', 'TEST_IF_COND_2'])])
enum FeatureEnum1
member eins
member zwei
@ -434,17 +434,17 @@ command test-command-features3 None -> None
command test-command-cond-features1 None -> None
gen=True success_response=True boxed=False oob=False preconfig=False
feature feature1
if defined(TEST_IF_FEATURE_1)
if TEST_IF_FEATURE_1
command test-command-cond-features2 None -> None
gen=True success_response=True boxed=False oob=False preconfig=False
feature feature1
if defined(TEST_IF_FEATURE_1)
if TEST_IF_FEATURE_1
feature feature2
if defined(TEST_IF_FEATURE_2)
if TEST_IF_FEATURE_2
command test-command-cond-features3 None -> None
gen=True success_response=True boxed=False oob=False preconfig=False
feature feature1
if OrderedDict([('all', ['defined(TEST_IF_COND_1)', 'defined(TEST_IF_COND_2)'])])
if OrderedDict([('all', ['TEST_IF_COND_1', 'TEST_IF_COND_2'])])
event TEST_EVENT_FEATURES0 FeatureStruct1
boxed=False
event TEST_EVENT_FEATURES1 None

View file

@ -1,3 +1,3 @@
# we reject duplicate events
{ 'event': 'EVENT_A', 'data': { 'myint': 'int' } }
{ 'event': 'EVENT_A', 'data': { 'myint': 'int' }, 'if': 'defined(FOO)' }
{ 'event': 'EVENT_A', 'data': { 'myint': 'int' }, 'if': 'FOO' }

View file

@ -1,2 +1,2 @@
union-branch-if-invalid.json: In union 'Uni':
union-branch-if-invalid.json:4: 'if' condition '' of 'data' member 'branch1' makes no sense
union-branch-if-invalid.json:4: 'if' condition '' of 'data' member 'branch1' is not a valid identifier