From patchwork Thu Sep 3 14:30:03 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 514095 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 481941402A3 for ; Fri, 4 Sep 2015 00:35:39 +1000 (AEST) Received: from localhost ([::1]:48557 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZXVc0-0004hS-TF for incoming@patchwork.ozlabs.org; Thu, 03 Sep 2015 10:35:37 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:32880) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZXVX8-0004Oa-AZ for qemu-devel@nongnu.org; Thu, 03 Sep 2015 10:30:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZXVX5-0005dD-JR for qemu-devel@nongnu.org; Thu, 03 Sep 2015 10:30:34 -0400 Received: from mx1.redhat.com ([209.132.183.28]:45760) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZXVX5-0005d2-A5 for qemu-devel@nongnu.org; Thu, 03 Sep 2015 10:30:31 -0400 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 09B8D8E3F3; Thu, 3 Sep 2015 14:30:31 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-45.ams2.redhat.com [10.36.116.45]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t83EURjf001301 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Thu, 3 Sep 2015 10:30:28 -0400 Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id C42FB300111D; Thu, 3 Sep 2015 16:30:24 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 3 Sep 2015 16:30:03 +0200 Message-Id: <1441290623-13631-13-git-send-email-armbru@redhat.com> In-Reply-To: <1441290623-13631-1-git-send-email-armbru@redhat.com> References: <1441290623-13631-1-git-send-email-armbru@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 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 RFC v4 12/32] qapi-commands: Convert to QAPISchemaVisitor 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 Output unchanged apart from reordering and white-space. Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake --- scripts/qapi-commands.py | 154 ++++++++++++++++++++++++++--------------------- scripts/qapi.py | 2 +- 2 files changed, 86 insertions(+), 70 deletions(-) diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py index 12bdc4c..e95fbb8 100644 --- a/scripts/qapi-commands.py +++ b/scripts/qapi-commands.py @@ -12,21 +12,22 @@ # This work is licensed under the terms of the GNU GPL, version 2. # See the COPYING file in the top-level directory. -from ordereddict import OrderedDict from qapi import * import re def generate_command_decl(name, args, ret_type): arglist="" - for argname, argtype, optional in parse_args(args): - argtype = c_type(argtype, is_param=True) - if optional: - arglist += "bool has_%s, " % c_name(argname) - arglist += "%s %s, " % (argtype, c_name(argname)) + if args: + for memb in args.members: + argtype = memb.type.c_type(is_param=True) + if memb.optional: + arglist += "bool has_%s, " % c_name(memb.name) + arglist += "%s %s, " % (argtype, c_name(memb.name)) return mcgen(''' %(ret_type)s qmp_%(name)s(%(args)sError **errp); ''', - ret_type=c_type(ret_type), name=c_name(name), + ret_type=(ret_type and ret_type.c_type()) or 'void', + name=c_name(name), args=arglist) def gen_err_check(err): @@ -45,10 +46,11 @@ def gen_sync_call(name, args, ret_type): retval="" if ret_type: retval = "retval = " - for argname, argtype, optional in parse_args(args): - if optional: - arglist += "has_%s, " % c_name(argname) - arglist += "%s, " % (c_name(argname)) + if args: + for memb in args.members: + if memb.optional: + arglist += "has_%s, " % c_name(memb.name) + arglist += "%s, " % c_name(memb.name) push_indent() ret = mcgen(''' %(retval)sqmp_%(name)s(%(args)s&local_err); @@ -68,7 +70,7 @@ def gen_visitor_input_containers_decl(args): ret = "" push_indent() - if len(args) > 0: + if args: ret += mcgen(''' QmpInputVisitor *mi = qmp_input_visitor_new_strict(QOBJECT(args)); QapiDeallocVisitor *md; @@ -81,22 +83,26 @@ Visitor *v; def gen_visitor_input_vars_decl(args): ret = "" push_indent() - for argname, argtype, optional in parse_args(args): - if optional: - ret += mcgen(''' + + if args: + for memb in args.members: + if memb.optional: + ret += mcgen(''' bool has_%(argname)s = false; ''', - argname=c_name(argname)) - if is_c_ptr(argtype): - ret += mcgen(''' + argname=c_name(memb.name)) + if is_c_ptr(memb.type.c_type()): + ret += mcgen(''' %(argtype)s %(argname)s = NULL; ''', - argname=c_name(argname), argtype=c_type(argtype)) - else: - ret += mcgen(''' + argname=c_name(memb.name), + argtype=memb.type.c_type()) + else: + ret += mcgen(''' %(argtype)s %(argname)s = {0}; ''', - argname=c_name(argname), argtype=c_type(argtype)) + argname=c_name(memb.name), + argtype=memb.type.c_type()) pop_indent() return ret @@ -106,7 +112,7 @@ def gen_visitor_input_block(args, dealloc=False): errparg = '&local_err' errarg = 'local_err' - if len(args) == 0: + if not args: return ret push_indent() @@ -124,25 +130,26 @@ v = qapi_dealloc_get_visitor(md); v = qmp_input_get_visitor(mi); ''') - for argname, argtype, optional in parse_args(args): - if optional: + for memb in args.members: + if memb.optional: ret += mcgen(''' visit_optional(v, &has_%(c_name)s, "%(name)s", %(errp)s); ''', - c_name=c_name(argname), name=argname, errp=errparg) + c_name=c_name(memb.name), name=memb.name, + errp=errparg) ret += gen_err_check(errarg) ret += mcgen(''' if (has_%(c_name)s) { ''', - c_name=c_name(argname)) + c_name=c_name(memb.name)) push_indent() ret += mcgen(''' visit_type_%(visitor)s(v, &%(c_name)s, "%(name)s", %(errp)s); ''', - c_name=c_name(argname), name=argname, argtype=argtype, - visitor=type_name(argtype), errp=errparg) + c_name=c_name(memb.name), name=memb.name, + visitor=memb.type.c_name(), errp=errparg) ret += gen_err_check(errarg) - if optional: + if memb.optional: pop_indent() ret += mcgen(''' } @@ -160,6 +167,7 @@ def gen_marshal_output(name, ret_type): return "" ret = mcgen(''' + static void qmp_marshal_output_%(c_name)s(%(c_ret_type)s ret_in, QObject **ret_out, Error **errp) { Error *local_err = NULL; @@ -183,8 +191,8 @@ out: qapi_dealloc_visitor_cleanup(md); } ''', - c_ret_type=c_type(ret_type), c_name=c_name(name), - visitor=type_name(ret_type)) + c_ret_type=ret_type.c_type(), c_name=c_name(name), + visitor=ret_type.c_name()) return ret @@ -198,6 +206,7 @@ def gen_marshal_input(name, args, ret_type, middle_mode): hdr = gen_marshal_input_decl(name, middle_mode) ret = mcgen(''' + %(header)s { Error *local_err = NULL; @@ -208,9 +217,9 @@ def gen_marshal_input(name, args, ret_type, middle_mode): ret += mcgen(''' %(c_type)s retval; ''', - c_type=c_type(ret_type)) + c_type=ret_type.c_type()) - if len(args) > 0: + if args: ret += gen_visitor_input_containers_decl(args) ret += gen_visitor_input_vars_decl(args) + '\n' ret += gen_visitor_input_block(args) + '\n' @@ -237,21 +246,23 @@ out: ''') return ret -def gen_registry(commands): - registry="" +def gen_register_command(name, success_response): push_indent() - for cmd in commands: - options = 'QCO_NO_OPTIONS' - if not cmd.get('success-response', True): - options = 'QCO_NO_SUCCESS_RESP' + options = 'QCO_NO_OPTIONS' + if not success_response: + options = 'QCO_NO_SUCCESS_RESP' - registry += mcgen(''' + ret = mcgen(''' qmp_register_command("%(name)s", qmp_marshal_input_%(c_name)s, %(opts)s); ''', - name=cmd['command'], c_name=c_name(cmd['command']), + name=name, c_name=c_name(name), opts=options) pop_indent() + return ret + +def gen_registry(registry): ret = mcgen(''' + static void qmp_init_marshal(void) { ''') @@ -263,6 +274,32 @@ qapi_init(qmp_init_marshal); ''') return ret +class QAPISchemaGenCommandVisitor(QAPISchemaVisitor): + def __init__(self): + self.decl = None + self.defn = None + self.regy = None + def visit_begin(self, schema): + self.decl = '' + self.defn = '' + self.regy = '' + def visit_end(self): + if not middle_mode: + self.defn += gen_registry(self.regy) + self.regy = None + def visit_command(self, name, info, arg_type, ret_type, + gen, success_response): + if not gen: + return + self.decl += generate_command_decl(name, arg_type, ret_type) + if ret_type: + self.defn += gen_marshal_output(name, ret_type) + if middle_mode: + self.decl += gen_marshal_input_decl(name, middle_mode) + ';\n' + self.defn += gen_marshal_input(name, arg_type, ret_type, middle_mode) + if not middle_mode: + self.regy += gen_register_command(name, success_response) + middle_mode = False (input_file, output_dir, do_c, do_h, prefix, opts) = \ @@ -272,10 +309,6 @@ for o, a in opts: if o in ("-m", "--middle"): middle_mode = True -exprs = QAPISchema(input_file).get_exprs() -commands = filter(lambda expr: expr.has_key('command'), exprs) -commands = filter(lambda expr: not expr.has_key('gen'), commands) - c_comment = ''' /* * schema-defined QMP->QAPI command dispatch @@ -331,29 +364,12 @@ fdecl.write(mcgen(''' #include "qapi/error.h" ''', - prefix=prefix)) + prefix=prefix)) -for cmd in commands: - arglist = [] - ret_type = None - if cmd.has_key('data'): - arglist = cmd['data'] - if cmd.has_key('returns'): - ret_type = cmd['returns'] - ret = generate_command_decl(cmd['command'], arglist, ret_type) - fdecl.write(ret) - if ret_type: - ret = gen_marshal_output(cmd['command'], ret_type) + "\n" - fdef.write(ret) - - if middle_mode: - fdecl.write('%s;\n' % gen_marshal_input_decl(cmd['command'], middle_mode)) - - ret = gen_marshal_input(cmd['command'], arglist, ret_type, middle_mode) + "\n" - fdef.write(ret) - -if not middle_mode: - ret = gen_registry(commands) - fdef.write(ret) +schema = QAPISchema(input_file) +gen = QAPISchemaGenCommandVisitor() +schema.visit(gen) +fdef.write(gen.defn) +fdecl.write(gen.decl) close_output(fdef, fdecl) diff --git a/scripts/qapi.py b/scripts/qapi.py index 3e7c154..923c3ac 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -1370,7 +1370,7 @@ def c_type(value, is_param=False): return c_name(value) + pointer_suffix def is_c_ptr(value): - return c_type(value).endswith(pointer_suffix) + return value.endswith(pointer_suffix) def genindent(count): ret = ""