From patchwork Mon Sep 21 21:57:26 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Blake X-Patchwork-Id: 520614 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 491C51401AF for ; Tue, 22 Sep 2015 08:07:51 +1000 (AEST) Received: from localhost ([::1]:34254 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ze9FV-0006He-90 for incoming@patchwork.ozlabs.org; Mon, 21 Sep 2015 18:07:49 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:60376) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ze96E-0007Xv-WB for qemu-devel@nongnu.org; Mon, 21 Sep 2015 17:58:18 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Ze96D-0000nx-Ln for qemu-devel@nongnu.org; Mon, 21 Sep 2015 17:58:14 -0400 Received: from mx1.redhat.com ([209.132.183.28]:48426) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ze96D-0000nl-Da for qemu-devel@nongnu.org; Mon, 21 Sep 2015 17:58:13 -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 10EA28EA2B; Mon, 21 Sep 2015 21:58:13 +0000 (UTC) Received: from red.redhat.com (ovpn-113-166.phx2.redhat.com [10.3.113.166]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t8LLw4bW027229; Mon, 21 Sep 2015 17:58:12 -0400 From: Eric Blake To: qemu-devel@nongnu.org Date: Mon, 21 Sep 2015 15:57:26 -0600 Message-Id: <1442872682-6523-11-git-send-email-eblake@redhat.com> In-Reply-To: <1442872682-6523-1-git-send-email-eblake@redhat.com> References: <1442872682-6523-1-git-send-email-eblake@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: Michael Roth , marcandre.lureau@redhat.com, DirtY.iCE.hu@gmail.com, armbru@redhat.com, ehabkost@redhat.com Subject: [Qemu-devel] [PATCH v5 10/46] qapi: Merge generation of per-member visits 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 Consolidate the code between visit, command marshalling, and event generation that iterates over the members of a struct. It reduces code duplication in the generator, with no change to generated marshal code, slightly more verbose visit code: | visit_optional(v, &(*obj)->has_device, "device", &err); |- if (!err && (*obj)->has_device) { |- visit_type_str(v, &(*obj)->device, "device", &err); |- } | if (err) { | goto out; | } |+ if ((*obj)->has_device) { |+ visit_type_str(v, &(*obj)->device, "device", &err); |+ if (err) { |+ goto out; |+ } |+ } and slightly more verbose event code (recall that the qmp output visitor has a no-op visit_optional()): |+ visit_optional(v, &has_offset, "offset", &err); |+ if (err) { |+ goto out; |+ } | if (has_offset) { | visit_type_int(v, &offset, "offset", &err); Signed-off-by: Eric Blake --- scripts/qapi-commands.py | 38 +--------------------------------- scripts/qapi-event.py | 35 +++----------------------------- scripts/qapi-visit.py | 26 +----------------------- scripts/qapi.py | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 94 deletions(-) diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py index 2151120..55287b1 100644 --- a/scripts/qapi-commands.py +++ b/scripts/qapi-commands.py @@ -25,17 +25,6 @@ def gen_command_decl(name, arg_type, ret_type): params=gen_params(arg_type, 'Error **errp')) -def gen_err_check(err): - if not err: - return '' - return mcgen(''' -if (%(err)s) { - goto out; -} -''', - err=err) - - def gen_call(name, arg_type, ret_type): ret = '' @@ -119,7 +108,6 @@ def gen_marshal_input_visit(arg_type, dealloc=False): push_indent() if dealloc: - errparg = 'NULL' errarg = None ret += mcgen(''' qmp_input_visitor_cleanup(mi); @@ -127,36 +115,12 @@ md = qapi_dealloc_visitor_new(); v = qapi_dealloc_get_visitor(md); ''') else: - errparg = '&err' errarg = 'err' ret += mcgen(''' v = qmp_input_get_visitor(mi); ''') - for memb in arg_type.members: - if memb.optional: - ret += mcgen(''' -visit_optional(v, &has_%(c_name)s, "%(name)s", %(errp)s); -''', - 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(memb.name)) - push_indent() - ret += mcgen(''' -visit_type_%(c_type)s(v, &%(c_name)s, "%(name)s", %(errp)s); -''', - c_name=c_name(memb.name), name=memb.name, - c_type=memb.type.c_name(), errp=errparg) - ret += gen_err_check(errarg) - if memb.optional: - pop_indent() - ret += mcgen(''' -} -''') + ret += gen_visit_fields(arg_type.members, '', False, errarg) if dealloc: ret += mcgen(''' diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py index b43bbc2..6c70a06 100644 --- a/scripts/qapi-event.py +++ b/scripts/qapi-event.py @@ -74,38 +74,9 @@ def gen_event_send(name, arg_type): ''', name=name) - - for memb in arg_type.members: - if memb.optional: - ret += mcgen(''' - if (has_%(c_name)s) { -''', - c_name=c_name(memb.name)) - push_indent() - - # Ugly: need to cast away the const - if memb.type.name == "str": - cast = '(char **)' - else: - cast = '' - - ret += mcgen(''' - visit_type_%(c_type)s(v, %(cast)s&%(c_name)s, "%(name)s", &err); - if (err) { - goto out; - } -''', - cast=cast, - c_name=c_name(memb.name), - c_type=memb.type.c_name(), - name=memb.name) - - if memb.optional: - pop_indent() - ret += mcgen(''' - } -''') - + push_indent() + ret += gen_visit_fields(arg_type.members, '', True, 'err') + pop_indent() ret += mcgen(''' visit_end_struct(v, &err); diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py index 9c0328d..1f287ba 100644 --- a/scripts/qapi-visit.py +++ b/scripts/qapi-visit.py @@ -88,31 +88,7 @@ if (err) { ''', c_type=base.c_name(), c_name=c_name('base')) - for memb in members: - if memb.optional: - ret += mcgen(''' -visit_optional(v, &(*obj)->has_%(c_name)s, "%(name)s", &err); -if (!err && (*obj)->has_%(c_name)s) { -''', - c_name=c_name(memb.name), name=memb.name) - push_indent() - - ret += mcgen(''' -visit_type_%(c_type)s(v, &(*obj)->%(c_name)s, "%(name)s", &err); -''', - c_type=memb.type.c_name(), c_name=c_name(memb.name), - name=memb.name) - - if memb.optional: - pop_indent() - ret += mcgen(''' -} -''') - ret += mcgen(''' -if (err) { - goto out; -} -''') + ret += gen_visit_fields(members, '(*obj)->', False, 'err') pop_indent() if re.search('^ *goto out;', ret, re.MULTILINE): diff --git a/scripts/qapi.py b/scripts/qapi.py index 6f4e471..7275daa 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -1531,6 +1531,59 @@ def gen_params(arg_type, extra): ret += sep + extra return ret + +def gen_err_check(err): + if not err: + return '' + return mcgen(''' +if (%(err)s) { + goto out; +} +''', + err=err) + + +def gen_visit_fields(members, prefix, need_cast, errarg): + ret = '' + if errarg: + errparg = '&' + errarg + else: + errparg = 'NULL' + for memb in members: + if memb.optional: + ret += mcgen(''' +visit_optional(v, &%(prefix)shas_%(c_name)s, "%(name)s", %(errp)s); +''', + prefix=prefix, c_name=c_name(memb.name), + name=memb.name, errp=errparg) + ret += gen_err_check(errarg) + ret += mcgen(''' +if (%(prefix)shas_%(c_name)s) { +''', + prefix=prefix, c_name=c_name(memb.name)) + push_indent() + + # Ugly: sometimes we need to cast away const + if need_cast and memb.type.name == 'str': + cast = '(char **)' + else: + cast = '' + + ret += mcgen(''' +visit_type_%(c_type)s(v, %(cast)s&%(prefix)s%(c_name)s, "%(name)s", %(errp)s); +''', + c_type=memb.type.c_name(), prefix=prefix, cast=cast, + c_name=c_name(memb.name), name=memb.name, + errp=errparg) + ret += gen_err_check(errarg) + + if memb.optional: + pop_indent() + ret += mcgen(''' +} +''') + return ret + # # Common command line parsing #