From patchwork Tue Jun 16 14:40:51 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 485041 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id BAF2A14027C for ; Wed, 17 Jun 2015 00:46:25 +1000 (AEST) Received: from localhost ([::1]:40701 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z4s87-0004ZN-O5 for incoming@patchwork.ozlabs.org; Tue, 16 Jun 2015 10:46:23 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43649) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z4s7L-0003ck-Tm for qemu-devel@nongnu.org; Tue, 16 Jun 2015 10:45:39 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Z4s7J-0008Ma-U8 for qemu-devel@nongnu.org; Tue, 16 Jun 2015 10:45:35 -0400 Received: from mx1.redhat.com ([209.132.183.28]:55255) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z4s2y-0005cI-FN for qemu-devel@nongnu.org; Tue, 16 Jun 2015 10:41:04 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 19C58376B6C; Tue, 16 Jun 2015 14:41:04 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-35.ams2.redhat.com [10.36.116.35]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t5GEf1Le003072 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Tue, 16 Jun 2015 10:41:03 -0400 Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 6411530438ED; Tue, 16 Jun 2015 16:40:59 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Tue, 16 Jun 2015 16:40:51 +0200 Message-Id: <1434465658-20782-9-git-send-email-armbru@redhat.com> In-Reply-To: <1434465658-20782-1-git-send-email-armbru@redhat.com> References: <1434465658-20782-1-git-send-email-armbru@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: mdroth@linux.vnet.ibm.com Subject: [Qemu-devel] [PATCH v2 08/15] qapi: Move exprs checking from parse_schema() to check_exprs() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org To have expression semantic analysis in one place rather than two. Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake --- 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)