qapi: Require valid names

Previous commits demonstrated that the generator overlooked various
bad naming situations:
- types, commands, and events need a valid name
- enum members must be valid names, when combined with prefix
- union and alternate branches cannot be marked optional

Valid upstream names match [a-zA-Z][a-zA-Z0-9_-]*; valid downstream
names match __[a-zA-Z][a-zA-Z0-9._-]*.  Enumerations match the
weaker [a-zA-Z0-9._-]+ (in part thanks to QKeyCode picking an enum
that starts with a digit, which we can't change now due to
backwards compatibility).  Rather than call out three separate
regex, this patch just uses a broader combination that allows both
upstream and downstream names, as well as a small hack that
realizes that any enum name is merely a suffix to an already valid
name prefix (that is, any enum name is valid if prepending _ fits
the normal rules).

We could reject new enumeration names beginning with a digit by
whitelisting existing exceptions.  We could also be stricter
about the distinction between upstream names (no leading
underscore, no use of dot) and downstream (mandatory leading
double underscore), but it is probably not worth the bother.

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
This commit is contained in:
Eric Blake 2015-05-04 09:05:22 -06:00 committed by Markus Armbruster
parent dd883c6f05
commit c9e0a79869
19 changed files with 60 additions and 43 deletions

View file

@ -0,0 +1 @@
tests/qapi-schema/bad-ident.json:2: 'type' does not allow optional name '*oops'

View file

@ -1 +1 @@
0
1

View file

@ -1,2 +1,2 @@
# FIXME: we should reject creating a type name with bad name
# we reject creating a type name with bad name
{ 'type': '*oops', 'data': { 'i': 'int' } }

View file

@ -1,3 +0,0 @@
[OrderedDict([('type', '*oops'), ('data', OrderedDict([('i', 'int')]))])]
[]
[OrderedDict([('type', '*oops'), ('data', OrderedDict([('i', 'int')]))])]

View file

@ -0,0 +1 @@
tests/qapi-schema/enum-bad-name.json:2: Member of enum 'MyEnum' uses invalid name 'not^possible'

View file

@ -1 +1 @@
0
1

View file

@ -1,2 +1,2 @@
# FIXME: we should ensure all enum names can map to C
# we ensure all enum names can map to C
{ 'enum': 'MyEnum', 'data': [ 'not^possible' ] }

View file

@ -1,3 +0,0 @@
[OrderedDict([('enum', 'MyEnum'), ('data', ['not^possible'])])]
[{'enum_name': 'MyEnum', 'enum_values': ['not^possible']}]
[]

View file

@ -1 +1 @@
tests/qapi-schema/enum-dict-member.json:2: Enum 'MyEnum' member 'OrderedDict([('value', 'str')])' is not a string
tests/qapi-schema/enum-dict-member.json:2: Member of enum 'MyEnum' requires a string name

View file

@ -1 +1 @@
tests/qapi-schema/flat-union-bad-discriminator.json:11: Flat union 'TestUnion' discriminator must be a string
tests/qapi-schema/flat-union-bad-discriminator.json:11: Discriminator of flat union 'TestUnion' requires a string name

View file

@ -0,0 +1 @@
tests/qapi-schema/flat-union-optional-discriminator.json:6: Discriminator of flat union 'MyUnion' does not allow optional name '*switch'

View file

@ -1,4 +1,4 @@
# FIXME: we should require the discriminator to be non-optional
# we require the discriminator to be non-optional
{ 'enum': 'Enum', 'data': [ 'one', 'two' ] }
{ 'type': 'Base',
'data': { '*switch': 'Enum' } }

View file

@ -1,7 +0,0 @@
[OrderedDict([('enum', 'Enum'), ('data', ['one', 'two'])]),
OrderedDict([('type', 'Base'), ('data', OrderedDict([('*switch', 'Enum')]))]),
OrderedDict([('type', 'Branch'), ('data', OrderedDict([('name', 'str')]))]),
OrderedDict([('union', 'MyUnion'), ('base', 'Base'), ('discriminator', '*switch'), ('data', OrderedDict([('one', 'Branch'), ('two', 'Branch')]))])]
[{'enum_name': 'Enum', 'enum_values': ['one', 'two']}]
[OrderedDict([('type', 'Base'), ('data', OrderedDict([('*switch', 'Enum')]))]),
OrderedDict([('type', 'Branch'), ('data', OrderedDict([('name', 'str')]))])]

View file

@ -0,0 +1 @@
tests/qapi-schema/union-optional-branch.json:2: Member of union 'Union' does not allow optional name '*a'

View file

@ -1 +1 @@
0
1

View file

@ -1,2 +1,2 @@
# FIXME: union branches cannot be optional
# union branches cannot be optional
{ 'union': 'Union', 'data': { '*a': 'int', 'b': 'str' } }

View file

@ -1,3 +0,0 @@
[OrderedDict([('union', 'Union'), ('data', OrderedDict([('*a', 'int'), ('b', 'str')]))])]
[{'enum_name': 'UnionKind', 'enum_values': None}]
[]