summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorMarkus Armbruster2021-03-23 10:40:05 +0100
committerMarkus Armbruster2021-03-23 22:30:08 +0100
commit5fbc78dd3675832062894aeca89a52c90a96f954 (patch)
tree05f136dbec6beab05b69343344c51f18049cccde /scripts
parentqapi: Fix to reject optional members with reserved names (diff)
downloadqemu-5fbc78dd3675832062894aeca89a52c90a96f954.tar.gz
qemu-5fbc78dd3675832062894aeca89a52c90a96f954.tar.xz
qemu-5fbc78dd3675832062894aeca89a52c90a96f954.zip
qapi: Permit flat union members for any tag value
Flat union branch names match the tag enum's member names. Omitted branches default to "no members for this tag value". Branch names starting with a digit get rejected like "'data' member '0' has an invalid name". However, omitting the branch works. This is because flat union tag values get checked twice: as enum member name, and as union branch name. The former accepts leading digits, the latter doesn't. Branches whose names start with a digit therefore cannot have members. Feels wrong. Get rid of the restriction by skipping the latter check. This can expose c_name() to input it can't handle: a name starting with a digit. Improve it to return a valid C identifier for any input. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210323094025.3569441-9-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> [Commit message rewritten]
Diffstat (limited to 'scripts')
-rw-r--r--scripts/qapi/common.py8
-rw-r--r--scripts/qapi/expr.py4
2 files changed, 7 insertions, 5 deletions
diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index 11b86beeab..cbd3fd81d3 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -18,7 +18,6 @@ from typing import Optional, Sequence
#: Magic string that gets removed along with all space to its right.
EATSPACE = '\033EATSPACE.'
POINTER_SUFFIX = ' *' + EATSPACE
-_C_NAME_TRANS = str.maketrans('.-', '__')
def camel_to_upper(value: str) -> str:
@@ -109,9 +108,10 @@ def c_name(name: str, protect: bool = True) -> str:
'not_eq', 'or', 'or_eq', 'xor', 'xor_eq'])
# namespace pollution:
polluted_words = set(['unix', 'errno', 'mips', 'sparc', 'i386'])
- name = name.translate(_C_NAME_TRANS)
- if protect and (name in c89_words | c99_words | c11_words | gcc_words
- | cpp_words | polluted_words):
+ name = re.sub(r'[^A-Za-z0-9_]', '_', name)
+ if protect and (name in (c89_words | c99_words | c11_words | gcc_words
+ | cpp_words | polluted_words)
+ or name[0].isdigit()):
return 'q_' + name
return name
diff --git a/scripts/qapi/expr.py b/scripts/qapi/expr.py
index cf09fa9fd3..507550c340 100644
--- a/scripts/qapi/expr.py
+++ b/scripts/qapi/expr.py
@@ -246,7 +246,9 @@ def check_union(expr, info):
for (key, value) in members.items():
source = "'data' member '%s'" % key
- check_name_str(key, info, source)
+ if discriminator is None:
+ check_name_str(key, info, source)
+ # else: name is in discriminator enum, which gets checked
check_keys(value, info, source, ['type'], ['if'])
check_if(value, info, source)
check_type(value['type'], info, source, allow_array=not base)