From patchwork Thu Oct 4 17:33:24 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Roth X-Patchwork-Id: 189305 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)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 4AEC02C03F0 for ; Fri, 5 Oct 2012 06:31:45 +1000 (EST) Received: from localhost ([::1]:54168 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TJpJd-0007ce-W6 for incoming@patchwork.ozlabs.org; Thu, 04 Oct 2012 13:34:29 -0400 Received: from eggs.gnu.org ([208.118.235.92]:48992) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TJpJC-0006XZ-Et for qemu-devel@nongnu.org; Thu, 04 Oct 2012 13:34:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TJpJ9-0000kg-Pe for qemu-devel@nongnu.org; Thu, 04 Oct 2012 13:34:02 -0400 Received: from mail-oa0-f45.google.com ([209.85.219.45]:46731) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TJpJ9-0000hT-Jo for qemu-devel@nongnu.org; Thu, 04 Oct 2012 13:33:59 -0400 Received: by mail-oa0-f45.google.com with SMTP id i18so707994oag.4 for ; Thu, 04 Oct 2012 10:33:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=uyehSbJz6JErhXu3CtDD4veuJ4P+VKpEUWNO14Rx7RE=; b=hiFbZs3f6aqqUU2M5h+6sALn5wkJo2QNYVveH3qKEKTOZEtMb3q7EkiViq2wtFAhMo iW3hasGqGYL2twDi2k8l/tledNwGAj64+i8wItpM54g1zU7l9p7f/VLBlHZ+t/1GetQz /eQjLWO18A34A46Kq6rsabK2qO8s9k8O04UycE9KpWFDGaOaA5/tRag+4CMNNEKS36Vx WlXSXHLbE3E1iSevBX5cKcBXwp4p0a/QFuXv/JZfqYq+439fGB56RbsxZOOUKT5GTRV4 R/3qcDAmDF+M+QOxULKU2uQlx984ERraoucYkVYSkof8Mu+/KtksYA/KuVqw/7lfWPdy o7hA== Received: by 10.182.172.74 with SMTP id ba10mr4926523obc.83.1349372039181; Thu, 04 Oct 2012 10:33:59 -0700 (PDT) Received: from loki.austin.ibm.com ([32.97.110.59]) by mx.google.com with ESMTPS id h2sm7131923obn.11.2012.10.04.10.33.57 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 04 Oct 2012 10:33:58 -0700 (PDT) From: Michael Roth To: qemu-devel@nongnu.org Date: Thu, 4 Oct 2012 12:33:24 -0500 Message-Id: <1349372021-31212-6-git-send-email-mdroth@linux.vnet.ibm.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1349372021-31212-1-git-send-email-mdroth@linux.vnet.ibm.com> References: <1349372021-31212-1-git-send-email-mdroth@linux.vnet.ibm.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.219.45 Cc: kwolf@redhat.com, peter.maydell@linaro.org, aliguori@us.ibm.com, blauwirbel@gmail.com, pbonzini@redhat.com, eblake@redhat.com Subject: [Qemu-devel] [PATCH v3 05/22] qapi: qapi_visit.py, support arrays and complex qapi definitions 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 Add support for arrays in the code generators. Complex field descriptions can now be used to provide additional information to the visitor generators, such as the max size of an array, or the field within a struct to use to determine how many elements are present in the array to avoid serializing uninitialized elements. Add handling for these in the code generators as well. Reviewed-by: Anthony Liguori Signed-off-by: Michael Roth --- scripts/qapi.py | 8 ++++-- scripts/qapi_commands.py | 8 +++--- scripts/qapi_types.py | 2 +- scripts/qapi_visit.py | 64 +++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 68 insertions(+), 14 deletions(-) diff --git a/scripts/qapi.py b/scripts/qapi.py index 122b4cb..a347203 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -110,12 +110,16 @@ def parse_args(typeinfo): argentry = typeinfo[member] optional = False structured = False + annotated = False if member.startswith('*'): argname = member[1:] optional = True if isinstance(argentry, OrderedDict): - structured = True - yield (argname, argentry, optional, structured) + if argentry.has_key(''): + annotated = True + else: + structured = True + yield (argname, argentry, optional, structured, annotated) def de_camel_case(name): new_name = '' diff --git a/scripts/qapi_commands.py b/scripts/qapi_commands.py index 3c4678d..a2e0c23 100644 --- a/scripts/qapi_commands.py +++ b/scripts/qapi_commands.py @@ -32,7 +32,7 @@ void %(visitor)s(Visitor *m, %(name)s * obj, const char *name, Error **errp); def generate_command_decl(name, args, ret_type): arglist="" - for argname, argtype, optional, structured in parse_args(args): + for argname, argtype, optional, structured, annotated in parse_args(args): argtype = c_type(argtype) if argtype == "char *": argtype = "const char *" @@ -50,7 +50,7 @@ def gen_sync_call(name, args, ret_type, indent=0): retval="" if ret_type: retval = "retval = " - for argname, argtype, optional, structured in parse_args(args): + for argname, argtype, optional, structured, annotated in parse_args(args): if optional: arglist += "has_%s, " % c_var(argname) arglist += "%s, " % (c_var(argname)) @@ -106,7 +106,7 @@ Visitor *v; def gen_visitor_input_vars_decl(args): ret = "" push_indent() - for argname, argtype, optional, structured in parse_args(args): + for argname, argtype, optional, structured, annotated in parse_args(args): if optional: ret += mcgen(''' bool has_%(argname)s = false; @@ -145,7 +145,7 @@ v = qmp_input_get_visitor(mi); ''', obj=obj) - for argname, argtype, optional, structured in parse_args(args): + for argname, argtype, optional, structured, annotated in parse_args(args): if optional: ret += mcgen(''' visit_start_optional(v, &has_%(c_name)s, "%(name)s", errp); diff --git a/scripts/qapi_types.py b/scripts/qapi_types.py index 49ef569..6518768 100644 --- a/scripts/qapi_types.py +++ b/scripts/qapi_types.py @@ -45,7 +45,7 @@ struct %(name)s ''', name=structname) - for argname, argentry, optional, structured in parse_args(members): + for argname, argentry, optional, structured, annotated in parse_args(members): if optional: ret += mcgen(''' bool has_%(c_name)s; diff --git a/scripts/qapi_visit.py b/scripts/qapi_visit.py index 974e458..b3f34a2 100644 --- a/scripts/qapi_visit.py +++ b/scripts/qapi_visit.py @@ -16,6 +16,52 @@ import sys import os import getopt import errno +import types + +def generate_visit_carray_body(name, info): + if info['array_size'][0].isdigit(): + array_size = info['array_size'] + elif info['array_size'][0] == '(' and info['array_size'][-1] == ')': + array_size = info['array_size'] + else: + array_size = "(*obj)->%s" % info['array_size'] + + if info.has_key('array_capacity'): + array_capacity = info['array_capacity'] + else: + array_capacity = array_size + + if camel_case(de_camel_case(info['type'][0])) == info['type'][0]: + ret = mcgen(''' +visit_start_carray(m, (void **)obj, "%(name)s", %(array_capacity)s, sizeof(%(type)s), errp); +int %(name)s_i; +for (%(name)s_i = 0; %(name)s_i < %(array_size)s; %(name)s_i++) { + %(type)s %(name)s_ptr = &(*obj)->%(name)s[%(name)s_i]; + visit_next_carray(m, errp); + visit_type_%(type_short)s(m, &%(name)s_ptr, NULL, errp); +} +visit_end_carray(m, errp); +''', + name=name, type=c_type(info['type'][0]), + type_short=info['type'][0], + array_size=array_size, + array_capacity=array_capacity) + else: + ret = mcgen(''' +visit_start_carray(m, (void **)obj, "%(name)s", %(array_capacity)s, sizeof(%(type)s), errp); +int %(name)s_i; +for (%(name)s_i = 0; %(name)s_i < %(array_size)s; %(name)s_i++) { + %(type)s *%(name)s_ptr = (%(type)s *)&(*obj)->%(name)s[%(name)s_i]; + visit_next_carray(m, errp); + visit_type_%(type_short)s(m, %(name)s_ptr, NULL, errp); +} +visit_end_carray(m, errp); +''', + name=name, type=c_type(info['type'][0]), + type_short=info['type'][0], + array_size=array_size, + array_capacity=array_capacity) + return ret def generate_visit_struct_body(field_prefix, name, members): ret = mcgen(''' @@ -45,10 +91,10 @@ if (!err) { push_indent() push_indent() - for argname, argentry, optional, structured in parse_args(members): + for argname, argentry, optional, structured, annotated in parse_args(members): if optional: ret += mcgen(''' -visit_start_optional(m, obj ? &(*obj)->%(c_prefix)shas_%(c_name)s : NULL, "%(name)s", &err); +visit_start_optional(m, obj ? &(*obj)->%(c_prefix)shas_%(c_name)s : NULL, "%(name)s", errp); if (obj && (*obj)->%(prefix)shas_%(c_name)s) { ''', c_prefix=c_var(field_prefix), prefix=field_prefix, @@ -58,12 +104,16 @@ if (obj && (*obj)->%(prefix)shas_%(c_name)s) { if structured: ret += generate_visit_struct_body(field_prefix + argname, argname, argentry) else: - ret += mcgen(''' -visit_type_%(type)s(m, obj ? &(*obj)->%(c_prefix)s%(c_name)s : NULL, "%(name)s", &err); + if annotated: + if isinstance(argentry['type'], types.ListType): + ret += generate_visit_carray_body(argname, argentry) + else: + ret += mcgen(''' +visit_type_%(type)s(m, obj ? &(*obj)->%(c_prefix)s%(c_name)s : NULL, "%(name)s", errp); ''', - c_prefix=c_var(field_prefix), prefix=field_prefix, - type=type_name(argentry), c_name=c_var(argname), - name=argname) + c_prefix=c_var(field_prefix), prefix=field_prefix, + type=type_name(argentry), c_name=c_var(argname), + name=argname) if optional: pop_indent()