qapi: Move exprs checking from parse_schema() to check_exprs()

To have expression semantic analysis in one place rather than two.

Backports commit 4d076d67c2c74662db092ecf4f99600b18209b2e from qemu
This commit is contained in:
Markus Armbruster 2018-02-19 15:44:18 -05:00 committed by Lioncash
parent 72e6966bba
commit 0a8ab4fc40
No known key found for this signature in database
GPG Key ID: 4E3C3CC1031BA9C7

View File

@ -602,26 +602,6 @@ def check_struct(expr, expr_info):
if expr.get('base'): if expr.get('base'):
check_member_clash(expr_info, expr['base'], expr['data']) check_member_clash(expr_info, expr['base'], expr['data'])
def check_exprs(schema):
for expr_elem in schema.exprs:
expr = expr_elem['expr']
info = expr_elem['info']
if expr.has_key('enum'):
check_enum(expr, info)
elif expr.has_key('union'):
check_union(expr, info)
elif expr.has_key('alternate'):
check_alternate(expr, info)
elif expr.has_key('struct'):
check_struct(expr, info)
elif expr.has_key('command'):
check_command(expr, info)
elif expr.has_key('event'):
check_event(expr, info)
else:
assert False, 'unexpected meta type'
def check_keys(expr_elem, meta, required, optional=[]): def check_keys(expr_elem, meta, required, optional=[]):
expr = expr_elem['expr'] expr = expr_elem['expr']
info = expr_elem['info'] info = expr_elem['info']
@ -645,24 +625,13 @@ def check_keys(expr_elem, meta, required, optional=[]):
"Key '%s' is missing from %s '%s'" "Key '%s' is missing from %s '%s'"
% (key, meta, name)) % (key, meta, name))
def check_exprs(exprs):
def parse_schema(fname):
global all_names global all_names
exprs = []
# First pass: read entire file into memory # Learn the types and check for valid expression keys
try:
schema = QAPISchema(open(fname, "r"))
except (QAPISchemaError, QAPIExprError), e:
print >>sys.stderr, e
exit(1)
try:
# Next pass: learn the types and check for valid expression keys. At
# this point, top-level 'include' has already been flattened.
for builtin in builtin_types.keys(): for builtin in builtin_types.keys():
all_names[builtin] = 'built-in' all_names[builtin] = 'built-in'
for expr_elem in schema.exprs: for expr_elem in exprs:
expr = expr_elem['expr'] expr = expr_elem['expr']
info = expr_elem['info'] info = expr_elem['info']
if expr.has_key('enum'): if expr.has_key('enum'):
@ -688,10 +657,9 @@ def parse_schema(fname):
else: else:
raise QAPIExprError(expr_elem['info'], raise QAPIExprError(expr_elem['info'],
"Expression is missing metatype") "Expression is missing metatype")
exprs.append(expr)
# Try again for hidden UnionKind enum # Try again for hidden UnionKind enum
for expr_elem in schema.exprs: for expr_elem in exprs:
expr = expr_elem['expr'] expr = expr_elem['expr']
if expr.has_key('union'): if expr.has_key('union'):
if not discriminator_find_enum_define(expr): if not discriminator_find_enum_define(expr):
@ -701,14 +669,36 @@ def parse_schema(fname):
add_enum('%sKind' % expr['alternate'], expr_elem['info'], add_enum('%sKind' % expr['alternate'], expr_elem['info'],
implicit=True) implicit=True)
# Final pass - validate that exprs make sense # Validate that exprs make sense
check_exprs(schema) for expr_elem in exprs:
except QAPIExprError, e: expr = expr_elem['expr']
info = expr_elem['info']
if expr.has_key('enum'):
check_enum(expr, info)
elif expr.has_key('union'):
check_union(expr, info)
elif expr.has_key('alternate'):
check_alternate(expr, info)
elif expr.has_key('struct'):
check_struct(expr, info)
elif expr.has_key('command'):
check_command(expr, info)
elif expr.has_key('event'):
check_event(expr, info)
else:
assert False, 'unexpected meta type'
return map(lambda expr_elem: expr_elem['expr'], exprs)
def parse_schema(fname):
try:
schema = QAPISchema(open(fname, "r"))
return check_exprs(schema.exprs)
except (QAPISchemaError, QAPIExprError), e:
print >>sys.stderr, e print >>sys.stderr, e
exit(1) exit(1)
return exprs
def parse_args(typeinfo): def parse_args(typeinfo):
if isinstance(typeinfo, str): if isinstance(typeinfo, str):
struct = find_struct(typeinfo) struct = find_struct(typeinfo)