From patchwork Thu Mar 29 17:26:42 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Capitulino X-Patchwork-Id: 149458 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 26F39B6EF4 for ; Fri, 30 Mar 2012 05:27:52 +1100 (EST) Received: from localhost ([::1]:42951 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SDJ8o-0001tG-1D for incoming@patchwork.ozlabs.org; Thu, 29 Mar 2012 13:28:06 -0400 Received: from eggs.gnu.org ([208.118.235.92]:41875) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SDJ7n-000802-AY for qemu-devel@nongnu.org; Thu, 29 Mar 2012 13:27:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SDJ7l-0003Zg-8O for qemu-devel@nongnu.org; Thu, 29 Mar 2012 13:27:02 -0400 Received: from mx1.redhat.com ([209.132.183.28]:19485) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SDJ7l-0003XV-13 for qemu-devel@nongnu.org; Thu, 29 Mar 2012 13:27:01 -0400 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q2THQvdn002944 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 29 Mar 2012 13:26:57 -0400 Received: from localhost (ovpn-113-102.phx2.redhat.com [10.3.113.102]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id q2THQuFU029308; Thu, 29 Mar 2012 13:26:57 -0400 From: Luiz Capitulino To: qemu-devel@nongnu.org Date: Thu, 29 Mar 2012 14:26:42 -0300 Message-Id: <1333042003-15490-13-git-send-email-lcapitulino@redhat.com> In-Reply-To: <1333042003-15490-1-git-send-email-lcapitulino@redhat.com> References: <1333042003-15490-1-git-send-email-lcapitulino@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: mdroth@linux.vnet.ibm.com, aliguori@us.ibm.com, kraxel@redhat.com, stefanha@linux.vnet.ibm.com, armbru@redhat.com Subject: [Qemu-devel] [PATCH 12/13] qapi: support for keyworded variable-length argument list 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 This allows for QAPI functions to receive a variable-length argument list. This is going to be used by device_add and netdev_add commands. In the schema, the argument list is represented by type name '**', like this example: { 'command': 'foo', 'data': { 'arg-list': '**' } } Each argument is represented by the KeyValues type and the C implementation should expect a KeyValuesList, like: void qmp_foo(KeyValuesList *values_list, Error **errp); XXX: This implementation is simple but very hacky. We just iterate through all arguments and build the KeyValuesList list to be passed to the QAPI function. Maybe we could have a kwargs type, that does exactly this but through a visitor instead? Signed-off-by: Luiz Capitulino --- qapi-schema.json | 15 +++++++++++++++ scripts/qapi-commands.py | 31 ++++++++++++++++++++++++++++--- scripts/qapi.py | 2 ++ 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/qapi-schema.json b/qapi-schema.json index 0d11d6e..25bd487 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -1701,3 +1701,18 @@ # Since: 1.1 ## { 'command': 'xen-save-devices-state', 'data': {'filename': 'str'} } + +## +# @KeyValues: +# +# A generic representation of a key value pair. +# +# @key: the name of the item +# +# @value: the string representation of the item value. This typically follows +# QEMU's command line parsing format. See the man pages for more +# information. +# +# Since: 0.14.0 +## +{ 'type': 'KeyValues', 'data': {'key': 'str', 'value': 'str'} } diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py index 30a24d2..75a6e81 100644 --- a/scripts/qapi-commands.py +++ b/scripts/qapi-commands.py @@ -146,19 +146,44 @@ v = qmp_input_get_visitor(mi); obj=obj) for argname, argtype, optional, structured in parse_args(args): - if optional: + if optional and not '**': ret += mcgen(''' visit_start_optional(v, &has_%(c_name)s, "%(name)s", errp); if (has_%(c_name)s) { ''', c_name=c_var(argname), name=argname) push_indent() - ret += mcgen(''' + if argtype == '**': + if dealloc: + ret += mcgen(''' +qapi_free_KeyValuesList(%(obj)s); +''', + obj=c_var(argname)) + else: + ret += mcgen(''' +{ + const QDictEntry *entry; + v = v; /* fix me baby */ + + for (entry = qdict_first(args); entry; entry = qdict_next(qdict, entry)) { + KeyValuesList *item = g_malloc0(sizeof(*item)); + item->value = g_malloc0(sizeof(*item->value)); + item->value->key = g_strdup(qdict_entry_key(entry)); + item->value->value = g_strdup(qstring_get_str(qobject_to_qstring(qdict_entry_value(entry)))); + + item->next = %(obj)s; + %(obj)s = item; + } +} +''', + obj=c_var(argname)) + else: + ret += mcgen(''' %(visitor)s(v, &%(c_name)s, "%(name)s", errp); ''', c_name=c_var(argname), name=argname, argtype=argtype, visitor=type_visitor(argtype)) - if optional: + if optional and not '**': pop_indent() ret += mcgen(''' } diff --git a/scripts/qapi.py b/scripts/qapi.py index e062336..87b9ee6 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -163,6 +163,8 @@ def c_type(name): return 'bool' elif name == 'number': return 'double' + elif name == '**': + return 'KeyValuesList *' elif type(name) == list: return '%s *' % c_list_type(name[0]) elif is_enum(name):