From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56502) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z3QIo-0003d1-MF for qemu-devel@nongnu.org; Fri, 12 Jun 2015 10:51:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Z3QIm-0001m8-7x for qemu-devel@nongnu.org; Fri, 12 Jun 2015 10:51:26 -0400 Received: from mx1.redhat.com ([209.132.183.28]:45884) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z3QIm-0001lX-13 for qemu-devel@nongnu.org; Fri, 12 Jun 2015 10:51:24 -0400 From: Markus Armbruster Date: Fri, 12 Jun 2015 16:51:07 +0200 Message-Id: <1434120674-8122-10-git-send-email-armbru@redhat.com> In-Reply-To: <1434120674-8122-1-git-send-email-armbru@redhat.com> References: <1434120674-8122-1-git-send-email-armbru@redhat.com> Subject: [Qemu-devel] [PATCH 09/16] qapi: Move exprs checking from parse_schema() to check_exprs() List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: mdroth@linux.vnet.ibm.com To have expression semantic analysis in one place rather than two. Signed-off-by: Markus Armbruster --- scripts/qapi.py | 142 ++++++++++++++++++++++++++------------------------------ 1 file changed, 66 insertions(+), 76 deletions(-) diff --git a/scripts/qapi.py b/scripts/qapi.py index 6faa897..34a5e8d 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -603,26 +603,6 @@ def check_struct(expr, expr_info): if expr.get('base'): 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=[]): expr = expr_elem['expr'] info = expr_elem['info'] @@ -646,70 +626,80 @@ def check_keys(expr_elem, meta, required, optional=[]): "Key '%s' is missing from %s '%s'" % (key, meta, name)) +def check_exprs(exprs): + global all_names + + # Learn the types and check for valid expression keys + for builtin in builtin_types.keys(): + all_names[builtin] = 'built-in' + for expr_elem in exprs: + expr = expr_elem['expr'] + info = expr_elem['info'] + if expr.has_key('enum'): + check_keys(expr_elem, 'enum', ['data']) + add_enum(expr['enum'], info, expr['data']) + elif expr.has_key('union'): + check_keys(expr_elem, 'union', ['data'], + ['base', 'discriminator']) + add_union(expr, info) + elif expr.has_key('alternate'): + check_keys(expr_elem, 'alternate', ['data']) + add_name(expr['alternate'], info, 'alternate') + elif expr.has_key('struct'): + check_keys(expr_elem, 'struct', ['data'], ['base']) + add_struct(expr, info) + elif expr.has_key('command'): + check_keys(expr_elem, 'command', [], + ['data', 'returns', 'gen', 'success-response']) + add_name(expr['command'], info, 'command') + elif expr.has_key('event'): + check_keys(expr_elem, 'event', [], ['data']) + add_name(expr['event'], info, 'event') + else: + raise QAPIExprError(expr_elem['info'], + "Expression is missing metatype") + + # Try again for hidden UnionKind enum + for expr_elem in exprs: + expr = expr_elem['expr'] + if expr.has_key('union'): + if not discriminator_find_enum_define(expr): + add_enum('%sKind' % expr['union'], expr_elem['info'], + implicit=True) + elif expr.has_key('alternate'): + add_enum('%sKind' % expr['alternate'], expr_elem['info'], + implicit=True) + + # Validate that exprs make sense + for expr_elem in 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' + + return map(lambda expr_elem: expr_elem['expr'], exprs) def parse_schema(fname): - global all_names - exprs = [] - - # First pass: read entire file into memory try: schema = QAPISchema(open(fname, "r")) + return check_exprs(schema.exprs) 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(): - all_names[builtin] = 'built-in' - for expr_elem in schema.exprs: - expr = expr_elem['expr'] - info = expr_elem['info'] - if expr.has_key('enum'): - check_keys(expr_elem, 'enum', ['data']) - add_enum(expr['enum'], info, expr['data']) - elif expr.has_key('union'): - check_keys(expr_elem, 'union', ['data'], - ['base', 'discriminator']) - add_union(expr, info) - elif expr.has_key('alternate'): - check_keys(expr_elem, 'alternate', ['data']) - add_name(expr['alternate'], info, 'alternate') - elif expr.has_key('struct'): - check_keys(expr_elem, 'struct', ['data'], ['base']) - add_struct(expr, info) - elif expr.has_key('command'): - check_keys(expr_elem, 'command', [], - ['data', 'returns', 'gen', 'success-response']) - add_name(expr['command'], info, 'command') - elif expr.has_key('event'): - check_keys(expr_elem, 'event', [], ['data']) - add_name(expr['event'], info, 'event') - else: - raise QAPIExprError(expr_elem['info'], - "Expression is missing metatype") - exprs.append(expr) - - # Try again for hidden UnionKind enum - for expr_elem in schema.exprs: - expr = expr_elem['expr'] - if expr.has_key('union'): - if not discriminator_find_enum_define(expr): - add_enum('%sKind' % expr['union'], expr_elem['info'], - implicit=True) - elif expr.has_key('alternate'): - add_enum('%sKind' % expr['alternate'], expr_elem['info'], - implicit=True) - - # Final pass - validate that exprs make sense - check_exprs(schema) - except QAPIExprError, e: - print >>sys.stderr, e - exit(1) - - return exprs - def parse_args(typeinfo): if isinstance(typeinfo, str): struct = find_struct(typeinfo) -- 1.9.3