From patchwork Fri May 8 13:34:06 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Capitulino X-Patchwork-Id: 470048 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 16B70140218 for ; Fri, 8 May 2015 23:37:13 +1000 (AEST) Received: from localhost ([::1]:55859 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YqiSl-0005hu-3X for incoming@patchwork.ozlabs.org; Fri, 08 May 2015 09:37:11 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41815) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YqiQ0-0000mN-6b for qemu-devel@nongnu.org; Fri, 08 May 2015 09:34:21 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YqiPz-0002VQ-1Y for qemu-devel@nongnu.org; Fri, 08 May 2015 09:34:20 -0400 Received: from mx1.redhat.com ([209.132.183.28]:55969) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YqiPy-0002V7-RW for qemu-devel@nongnu.org; Fri, 08 May 2015 09:34:18 -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 6DCDB8EA4A; Fri, 8 May 2015 13:34:18 +0000 (UTC) Received: from localhost (ovpn-113-30.phx2.redhat.com [10.3.113.30]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t48DYHiC023324; Fri, 8 May 2015 09:34:18 -0400 From: Luiz Capitulino To: peter.maydell@linaro.org Date: Fri, 8 May 2015 09:34:06 -0400 Message-Id: <1431092051-31046-6-git-send-email-lcapitulino@redhat.com> In-Reply-To: <1431092051-31046-1-git-send-email-lcapitulino@redhat.com> References: <1431092051-31046-1-git-send-email-lcapitulino@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: qemu-devel@nongnu.org Subject: [Qemu-devel] [PULL 05/10] json-parser: Accept 'null' in QMP 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 From: Eric Blake We document that in QMP, the client may send any json-value for the optional "id" key, and then return that same value on reply (both success and failures, insofar as the failure happened after parsing the id). [Note that the output may not be identical to the input, as whitespace may change and since we may reorder keys within a json-object, but that this still constitutes the same json-value]. However, we were not handling the JSON literal null, which counts as a json-value per RFC 7159. Also, down the road, given the QAPI schema of {'*foo':'str'} or {'*foo':'ComplexType'}, we could decide to allow the QMP client to pass { "foo":null } instead of the current representation of { } where omitting the key is the only way to get at the default NULL value. Such a change might be useful for argument introspection (if a type in older qemu lacks 'foo' altogether, then an explicit "foo":null probe will force an easily distinguished error message for whether the optional "foo" key is even understood in newer qemu). And if we add default values to optional arguments, allowing an explicit null would be required for getting a NULL value associated with an optional string that has a non-null default. But all that can come at a later day. The 'check-unit' testsuite is enhanced to test that parsing produces the same object as explicitly requesting a reference to the special qnull object. In addition, I tested with: $ ./x86_64-softmmu/qemu-system-x86_64 -qmp stdio -nodefaults {"QMP": {"version": {"qemu": {"micro": 91, "minor": 2, "major": 2}, "package": ""}, "capabilities": []}} {"execute":"qmp_capabilities","id":null} {"return": {}, "id": null} {"id":{"a":null,"b":[1,null]},"execute":"quit"} {"return": {}, "id": {"a": null, "b": [1, null]}} {"timestamp": {"seconds": 1427742379, "microseconds": 423128}, "event": "SHUTDOWN"} Signed-off-by: Eric Blake Signed-off-by: Markus Armbruster Signed-off-by: Luiz Capitulino --- qobject/json-parser.c | 2 ++ tests/check-qjson.c | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/qobject/json-parser.c b/qobject/json-parser.c index 4288267..717cb8f 100644 --- a/qobject/json-parser.c +++ b/qobject/json-parser.c @@ -561,6 +561,8 @@ static QObject *parse_keyword(JSONParserContext *ctxt) ret = QOBJECT(qbool_from_int(true)); } else if (token_is_keyword(token, "false")) { ret = QOBJECT(qbool_from_int(false)); + } else if (token_is_keyword(token, "null")) { + ret = qnull(); } else { parse_error(ctxt, token, "invalid keyword `%s'", token_get_value(token)); goto out; diff --git a/tests/check-qjson.c b/tests/check-qjson.c index 95497a0..60e5b22 100644 --- a/tests/check-qjson.c +++ b/tests/check-qjson.c @@ -1,6 +1,6 @@ /* * Copyright IBM, Corp. 2009 - * Copyright (c) 2013 Red Hat Inc. + * Copyright (c) 2013, 2015 Red Hat Inc. * * Authors: * Anthony Liguori @@ -1005,6 +1005,7 @@ static void keyword_literal(void) { QObject *obj; QBool *qbool; + QObject *null; QString *str; obj = qobject_from_json("true"); @@ -1041,7 +1042,7 @@ static void keyword_literal(void) g_assert(qbool_get_int(qbool) == 0); QDECREF(qbool); - + obj = qobject_from_jsonf("%i", true); g_assert(obj != NULL); g_assert(qobject_type(obj) == QTYPE_QBOOL); @@ -1050,6 +1051,16 @@ static void keyword_literal(void) g_assert(qbool_get_int(qbool) != 0); QDECREF(qbool); + + obj = qobject_from_json("null"); + g_assert(obj != NULL); + g_assert(qobject_type(obj) == QTYPE_QNULL); + + null = qnull(); + g_assert(null == obj); + + qobject_decref(obj); + qobject_decref(null); } typedef struct LiteralQDictEntry LiteralQDictEntry;