From patchwork Thu Dec 13 18:43:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 1013076 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43G37t3SBKz9s9G for ; Fri, 14 Dec 2018 06:06:50 +1100 (AEDT) Received: from localhost ([::1]:54350 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXWJs-0008Ms-2Q for incoming@patchwork.ozlabs.org; Thu, 13 Dec 2018 14:06:48 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53321) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVxv-0005pm-IG for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:08 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXVxr-0002iW-NZ for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:05 -0500 Received: from mx1.redhat.com ([209.132.183.28]:47410) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gXVxp-0001JY-L0 for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:03 -0500 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8924A9D50B for ; Thu, 13 Dec 2018 18:43:44 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-56.ams2.redhat.com [10.36.116.56]) by smtp.corp.redhat.com (Postfix) with ESMTPS id CA8CA5D6A9; Thu, 13 Dec 2018 18:43:41 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 405F311385A7; Thu, 13 Dec 2018 19:43:40 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2018 19:43:09 +0100 Message-Id: <20181213184340.24037-2-armbru@redhat.com> In-Reply-To: <20181213184340.24037-1-armbru@redhat.com> References: <20181213184340.24037-1-armbru@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Thu, 13 Dec 2018 18:43:44 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 01/32] cutils: Add qemu_strtod() and qemu_strtod_finite() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: David Hildenbrand Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: David Hildenbrand Let's provide a wrapper for strtod(). Reviewed-by: Markus Armbruster Signed-off-by: David Hildenbrand Message-Id: <20181121164421.20780-2-david@redhat.com> Signed-off-by: Markus Armbruster --- include/qemu/cutils.h | 2 ++ util/cutils.c | 65 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/include/qemu/cutils.h b/include/qemu/cutils.h index 7071bfe2d4..756b41c193 100644 --- a/include/qemu/cutils.h +++ b/include/qemu/cutils.h @@ -146,6 +146,8 @@ int qemu_strtoi64(const char *nptr, const char **endptr, int base, int64_t *result); int qemu_strtou64(const char *nptr, const char **endptr, int base, uint64_t *result); +int qemu_strtod(const char *nptr, const char **endptr, double *result); +int qemu_strtod_finite(const char *nptr, const char **endptr, double *result); int parse_uint(const char *s, unsigned long long *value, char **endptr, int base); diff --git a/util/cutils.c b/util/cutils.c index 0621565930..ec0a401d9a 100644 --- a/util/cutils.c +++ b/util/cutils.c @@ -551,6 +551,71 @@ int qemu_strtou64(const char *nptr, const char **endptr, int base, return check_strtox_error(nptr, ep, endptr, errno); } +/** + * Convert string @nptr to a double. + * + * This is a wrapper around strtod() that is harder to misuse. + * Semantics of @nptr and @endptr match strtod() with differences + * noted below. + * + * @nptr may be null, and no conversion is performed then. + * + * If no conversion is performed, store @nptr in *@endptr and return + * -EINVAL. + * + * If @endptr is null, and the string isn't fully converted, return + * -EINVAL. This is the case when the pointer that would be stored in + * a non-null @endptr points to a character other than '\0'. + * + * If the conversion overflows, store +/-HUGE_VAL in @result, depending + * on the sign, and return -ERANGE. + * + * If the conversion underflows, store +/-0.0 in @result, depending on the + * sign, and return -ERANGE. + * + * Else store the converted value in @result, and return zero. + */ +int qemu_strtod(const char *nptr, const char **endptr, double *result) +{ + char *ep; + + if (!nptr) { + if (endptr) { + *endptr = nptr; + } + return -EINVAL; + } + + errno = 0; + *result = strtod(nptr, &ep); + return check_strtox_error(nptr, ep, endptr, errno); +} + +/** + * Convert string @nptr to a finite double. + * + * Works like qemu_strtod(), except that "NaN" and "inf" are rejected + * with -EINVAL and no conversion is performed. + */ +int qemu_strtod_finite(const char *nptr, const char **endptr, double *result) +{ + double tmp; + int ret; + + ret = qemu_strtod(nptr, endptr, &tmp); + if (!ret && !isfinite(tmp)) { + if (endptr) { + *endptr = nptr; + } + ret = -EINVAL; + } + + if (ret != -EINVAL) { + *result = tmp; + } + return ret; +} + /** * Searches for the first occurrence of 'c' in 's', and returns a pointer * to the trailing null byte if none was found. From patchwork Thu Dec 13 18:43:10 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 1013045 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43G2k95Z1yz9rxp for ; Fri, 14 Dec 2018 05:48:01 +1100 (AEDT) Received: from localhost ([::1]:54250 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXW1f-0008LX-93 for incoming@patchwork.ozlabs.org; Thu, 13 Dec 2018 13:47:59 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53202) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVxo-0005hd-Hg for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:02 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXVxj-00029v-KT for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:59 -0500 Received: from mx1.redhat.com ([209.132.183.28]:32852) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gXVxj-0001Gx-3P for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:55 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 389F6C0BEAB4 for ; Thu, 13 Dec 2018 18:43:44 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-56.ams2.redhat.com [10.36.116.56]) by smtp.corp.redhat.com (Postfix) with ESMTPS id CF783105706B; Thu, 13 Dec 2018 18:43:41 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 4495F11385CB; Thu, 13 Dec 2018 19:43:40 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2018 19:43:10 +0100 Message-Id: <20181213184340.24037-3-armbru@redhat.com> In-Reply-To: <20181213184340.24037-1-armbru@redhat.com> References: <20181213184340.24037-1-armbru@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Thu, 13 Dec 2018 18:43:44 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 02/32] cutils: Fix qemu_strtosz() & friends to reject non-finite sizes X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: David Hildenbrand Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: David Hildenbrand qemu_strtosz() & friends reject NaNs, but happily accept infinities. They shouldn't. Fix that. The fix makes use of qemu_strtod_finite(). To avoid ugly casts, change the @end parameter of qemu_strtosz() & friends from char ** to const char **. Also, add two test cases, testing that "inf" and "NaN" are properly rejected. While at it, also fixup the function documentation. Reviewed-by: Eric Blake Reviewed-by: Markus Armbruster Signed-off-by: David Hildenbrand Message-Id: <20181121164421.20780-3-david@redhat.com> Signed-off-by: Markus Armbruster --- include/qemu/cutils.h | 6 +++--- monitor.c | 2 +- tests/test-cutils.c | 24 +++++++++++++++++------- util/cutils.c | 18 ++++++++---------- 4 files changed, 29 insertions(+), 21 deletions(-) diff --git a/include/qemu/cutils.h b/include/qemu/cutils.h index 756b41c193..d2dad3057c 100644 --- a/include/qemu/cutils.h +++ b/include/qemu/cutils.h @@ -153,9 +153,9 @@ int parse_uint(const char *s, unsigned long long *value, char **endptr, int base); int parse_uint_full(const char *s, unsigned long long *value, int base); -int qemu_strtosz(const char *nptr, char **end, uint64_t *result); -int qemu_strtosz_MiB(const char *nptr, char **end, uint64_t *result); -int qemu_strtosz_metric(const char *nptr, char **end, uint64_t *result); +int qemu_strtosz(const char *nptr, const char **end, uint64_t *result); +int qemu_strtosz_MiB(const char *nptr, const char **end, uint64_t *result); +int qemu_strtosz_metric(const char *nptr, const char **end, uint64_t *result); /* used to print char* safely */ #define STR_OR_NULL(str) ((str) ? (str) : "null") diff --git a/monitor.c b/monitor.c index 6e81b09294..cf9cece965 100644 --- a/monitor.c +++ b/monitor.c @@ -3232,7 +3232,7 @@ static QDict *monitor_parse_arguments(Monitor *mon, { int ret; uint64_t val; - char *end; + const char *end; while (qemu_isspace(*p)) { p++; diff --git a/tests/test-cutils.c b/tests/test-cutils.c index d85c3e0f6d..1aa8351520 100644 --- a/tests/test-cutils.c +++ b/tests/test-cutils.c @@ -1950,7 +1950,7 @@ static void test_qemu_strtou64_full_max(void) static void test_qemu_strtosz_simple(void) { const char *str; - char *endptr = NULL; + const char *endptr; int err; uint64_t res = 0xbaadf00d; @@ -2017,7 +2017,7 @@ static void test_qemu_strtosz_units(void) const char *p = "1P"; const char *e = "1E"; int err; - char *endptr = NULL; + const char *endptr; uint64_t res = 0xbaadf00d; /* default is M */ @@ -2066,7 +2066,7 @@ static void test_qemu_strtosz_float(void) { const char *str = "12.345M"; int err; - char *endptr = NULL; + const char *endptr; uint64_t res = 0xbaadf00d; err = qemu_strtosz(str, &endptr, &res); @@ -2078,7 +2078,7 @@ static void test_qemu_strtosz_float(void) static void test_qemu_strtosz_invalid(void) { const char *str; - char *endptr = NULL; + const char *endptr; int err; uint64_t res = 0xbaadf00d; @@ -2096,12 +2096,22 @@ static void test_qemu_strtosz_invalid(void) err = qemu_strtosz(str, &endptr, &res); g_assert_cmpint(err, ==, -EINVAL); g_assert(endptr == str); + + str = "inf"; + err = qemu_strtosz(str, &endptr, &res); + g_assert_cmpint(err, ==, -EINVAL); + g_assert(endptr == str); + + str = "NaN"; + err = qemu_strtosz(str, &endptr, &res); + g_assert_cmpint(err, ==, -EINVAL); + g_assert(endptr == str); } static void test_qemu_strtosz_trailing(void) { const char *str; - char *endptr = NULL; + const char *endptr; int err; uint64_t res = 0xbaadf00d; @@ -2126,7 +2136,7 @@ static void test_qemu_strtosz_trailing(void) static void test_qemu_strtosz_erange(void) { const char *str; - char *endptr = NULL; + const char *endptr; int err; uint64_t res = 0xbaadf00d; @@ -2160,7 +2170,7 @@ static void test_qemu_strtosz_metric(void) { const char *str = "12345k"; int err; - char *endptr = NULL; + const char *endptr; uint64_t res = 0xbaadf00d; err = qemu_strtosz_metric(str, &endptr, &res); diff --git a/util/cutils.c b/util/cutils.c index ec0a401d9a..e098debdc0 100644 --- a/util/cutils.c +++ b/util/cutils.c @@ -203,23 +203,21 @@ static int64_t suffix_mul(char suffix, int64_t unit) /* * Convert string to bytes, allowing either B/b for bytes, K/k for KB, * M/m for MB, G/g for GB or T/t for TB. End pointer will be returned - * in *end, if not NULL. Return -ERANGE on overflow, Return -EINVAL on + * in *end, if not NULL. Return -ERANGE on overflow, and -EINVAL on * other error. */ -static int do_strtosz(const char *nptr, char **end, +static int do_strtosz(const char *nptr, const char **end, const char default_suffix, int64_t unit, uint64_t *result) { int retval; - char *endptr; + const char *endptr; unsigned char c; int mul_required = 0; double val, mul, integral, fraction; - errno = 0; - val = strtod(nptr, &endptr); - if (isnan(val) || endptr == nptr || errno != 0) { - retval = -EINVAL; + retval = qemu_strtod_finite(nptr, &endptr, &val); + if (retval) { goto out; } fraction = modf(val, &integral); @@ -259,17 +257,17 @@ out: return retval; } -int qemu_strtosz(const char *nptr, char **end, uint64_t *result) +int qemu_strtosz(const char *nptr, const char **end, uint64_t *result) { return do_strtosz(nptr, end, 'B', 1024, result); } -int qemu_strtosz_MiB(const char *nptr, char **end, uint64_t *result) +int qemu_strtosz_MiB(const char *nptr, const char **end, uint64_t *result) { return do_strtosz(nptr, end, 'M', 1024, result); } -int qemu_strtosz_metric(const char *nptr, char **end, uint64_t *result) +int qemu_strtosz_metric(const char *nptr, const char **end, uint64_t *result) { return do_strtosz(nptr, end, 'B', 1000, result); } From patchwork Thu Dec 13 18:43:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 1013040 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43G2fG5LjSz9sBQ for ; Fri, 14 Dec 2018 05:44:37 +1100 (AEDT) Received: from localhost ([::1]:54228 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVyL-0005dz-Rc for incoming@patchwork.ozlabs.org; Thu, 13 Dec 2018 13:44:33 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53090) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVxi-0005c8-8W for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:55 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXVxc-0001Zj-OB for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:50 -0500 Received: from mx1.redhat.com ([209.132.183.28]:43090) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gXVxc-0001Gc-D9 for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:48 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 130A13086249 for ; Thu, 13 Dec 2018 18:43:44 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-56.ams2.redhat.com [10.36.116.56]) by smtp.corp.redhat.com (Postfix) with ESMTPS id CAFA11057042; Thu, 13 Dec 2018 18:43:41 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 47A101138538; Thu, 13 Dec 2018 19:43:40 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2018 19:43:11 +0100 Message-Id: <20181213184340.24037-4-armbru@redhat.com> In-Reply-To: <20181213184340.24037-1-armbru@redhat.com> References: <20181213184340.24037-1-armbru@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.49]); Thu, 13 Dec 2018 18:43:44 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 03/32] qapi: Fix string-input-visitor to reject NaN and infinities X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: David Hildenbrand Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: David Hildenbrand The string-input-visitor happily accepts NaN and infinities when parsing numbers (doubles). They shouldn't. Fix that. Also, add two test cases, testing if "NaN" and "inf" is properly rejected. Reviewed-by: Eric Blake Reviewed-by: Markus Armbruster Signed-off-by: David Hildenbrand Message-Id: <20181121164421.20780-4-david@redhat.com> Signed-off-by: Markus Armbruster --- qapi/string-input-visitor.c | 6 ++---- tests/test-string-input-visitor.c | 13 +++++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c index b3fdd0827d..b89c6c4e06 100644 --- a/qapi/string-input-visitor.c +++ b/qapi/string-input-visitor.c @@ -20,6 +20,7 @@ #include "qemu/option.h" #include "qemu/queue.h" #include "qemu/range.h" +#include "qemu/cutils.h" struct StringInputVisitor @@ -313,12 +314,9 @@ static void parse_type_number(Visitor *v, const char *name, double *obj, Error **errp) { StringInputVisitor *siv = to_siv(v); - char *endp = (char *) siv->string; double val; - errno = 0; - val = strtod(siv->string, &endp); - if (errno || endp == siv->string || *endp) { + if (qemu_strtod_finite(siv->string, NULL, &val)) { error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", "number"); return; diff --git a/tests/test-string-input-visitor.c b/tests/test-string-input-visitor.c index 88e0e1aa9a..1efba06948 100644 --- a/tests/test-string-input-visitor.c +++ b/tests/test-string-input-visitor.c @@ -252,6 +252,19 @@ static void test_visitor_in_number(TestInputVisitorData *data, visit_type_number(v, NULL, &res, &err); g_assert(!err); g_assert_cmpfloat(res, ==, value); + + /* NaN and infinity has to be rejected */ + + v = visitor_input_test_init(data, "NaN"); + + visit_type_number(v, NULL, &res, &err); + error_free_or_abort(&err); + + v = visitor_input_test_init(data, "inf"); + + visit_type_number(v, NULL, &res, &err); + error_free_or_abort(&err); + } static void test_visitor_in_string(TestInputVisitorData *data, From patchwork Thu Dec 13 18:43:12 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 1013052 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43G2sK3sDBz9s3Z for ; Fri, 14 Dec 2018 05:54:13 +1100 (AEDT) Received: from localhost ([::1]:54276 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXW7e-0005fc-KO for incoming@patchwork.ozlabs.org; Thu, 13 Dec 2018 13:54:10 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53114) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVxj-0005ci-8R for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:58 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXVxe-0001jU-So for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:54 -0500 Received: from mx1.redhat.com ([209.132.183.28]:47406) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gXVxc-0001JK-Mk for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:48 -0500 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7AE825D5EA for ; Thu, 13 Dec 2018 18:43:44 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-56.ams2.redhat.com [10.36.116.56]) by smtp.corp.redhat.com (Postfix) with ESMTPS id CAC921992A; Thu, 13 Dec 2018 18:43:41 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 4D99A11384AA; Thu, 13 Dec 2018 19:43:40 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2018 19:43:12 +0100 Message-Id: <20181213184340.24037-5-armbru@redhat.com> In-Reply-To: <20181213184340.24037-1-armbru@redhat.com> References: <20181213184340.24037-1-armbru@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Thu, 13 Dec 2018 18:43:44 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 04/32] qapi: Use qemu_strtod_finite() in qobject-input-visitor X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: David Hildenbrand Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: David Hildenbrand Let's use the new function. Just as current behavior, we have to consume the whole string (now it's just way clearer what's going on). Reviewed-by: Eric Blake Reviewed-by: Markus Armbruster Signed-off-by: David Hildenbrand Message-Id: <20181121164421.20780-5-david@redhat.com> Signed-off-by: Markus Armbruster --- qapi/qobject-input-visitor.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/qapi/qobject-input-visitor.c b/qapi/qobject-input-visitor.c index 3e88b27f9e..07465f9947 100644 --- a/qapi/qobject-input-visitor.c +++ b/qapi/qobject-input-visitor.c @@ -562,19 +562,20 @@ static void qobject_input_type_number_keyval(Visitor *v, const char *name, { QObjectInputVisitor *qiv = to_qiv(v); const char *str = qobject_input_get_keyval(qiv, name, errp); - char *endp; + double val; if (!str) { return; } - errno = 0; - *obj = strtod(str, &endp); - if (errno || endp == str || *endp || !isfinite(*obj)) { + if (qemu_strtod_finite(str, NULL, &val)) { /* TODO report -ERANGE more nicely */ error_setg(errp, QERR_INVALID_PARAMETER_TYPE, full_name(qiv, name), "number"); + return; } + + *obj = val; } static void qobject_input_type_any(Visitor *v, const char *name, QObject **obj, From patchwork Thu Dec 13 18:43:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 1013046 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43G2kd2Mjpz9s4s for ; Fri, 14 Dec 2018 05:48:25 +1100 (AEDT) Received: from localhost ([::1]:54251 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXW22-0000C8-Rm for incoming@patchwork.ozlabs.org; Thu, 13 Dec 2018 13:48:22 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53189) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVxo-0005hU-GY for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXVxl-0002FX-4W for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:59 -0500 Received: from mx1.redhat.com ([209.132.183.28]:43100) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gXVxj-0001P8-IR for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:55 -0500 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B54CA307CDE5 for ; Thu, 13 Dec 2018 18:43:45 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-56.ams2.redhat.com [10.36.116.56]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 6D9F760BE7; Thu, 13 Dec 2018 18:43:43 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 539C81138406; Thu, 13 Dec 2018 19:43:40 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2018 19:43:13 +0100 Message-Id: <20181213184340.24037-6-armbru@redhat.com> In-Reply-To: <20181213184340.24037-1-armbru@redhat.com> References: <20181213184340.24037-1-armbru@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.49]); Thu, 13 Dec 2018 18:43:45 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 05/32] test-string-input-visitor: Add more tests X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: David Hildenbrand Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: David Hildenbrand Test that very big/small values are not accepted and that ranges with only one element work. Also test that ranges are ascending and cannot have more than 65536 elements. Rename expect4 to expect5, as we will be moving that to a separate ulist test after the rework. Reviewed-by: Eric Blake Reviewed-by: Markus Armbruster Signed-off-by: David Hildenbrand Message-Id: <20181121164421.20780-6-david@redhat.com> Signed-off-by: Markus Armbruster --- tests/test-string-input-visitor.c | 41 +++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/tests/test-string-input-visitor.c b/tests/test-string-input-visitor.c index 1efba06948..8ee0d1b284 100644 --- a/tests/test-string-input-visitor.c +++ b/tests/test-string-input-visitor.c @@ -121,7 +121,8 @@ static void test_visitor_in_intList(TestInputVisitorData *data, int64_t expect1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20 }; int64_t expect2[] = { 32767, -32768, -32767 }; int64_t expect3[] = { INT64_MAX, INT64_MIN }; - uint64_t expect4[] = { UINT64_MAX }; + int64_t expect4[] = { 1 }; + uint64_t expect5[] = { UINT64_MAX }; Error *err = NULL; int64List *res = NULL; int64List *tail; @@ -140,8 +141,44 @@ static void test_visitor_in_intList(TestInputVisitorData *data, "-9223372036854775808,9223372036854775807"); check_ilist(v, expect3, ARRAY_SIZE(expect3)); + v = visitor_input_test_init(data, "1-1"); + check_ilist(v, expect4, ARRAY_SIZE(expect4)); + v = visitor_input_test_init(data, "18446744073709551615"); - check_ulist(v, expect4, ARRAY_SIZE(expect4)); + check_ulist(v, expect5, ARRAY_SIZE(expect5)); + + /* Value too large */ + + v = visitor_input_test_init(data, "9223372036854775808"); + visit_type_int64List(v, NULL, &res, &err); + error_free_or_abort(&err); + g_assert(!res); + + /* Value too small */ + + v = visitor_input_test_init(data, "-9223372036854775809"); + visit_type_int64List(v, NULL, &res, &err); + error_free_or_abort(&err); + g_assert(!res); + + /* Range not ascending */ + + v = visitor_input_test_init(data, "3-1"); + visit_type_int64List(v, NULL, &res, &err); + error_free_or_abort(&err); + g_assert(!res); + + v = visitor_input_test_init(data, "9223372036854775807-0"); + visit_type_int64List(v, NULL, &res, &err); + error_free_or_abort(&err); + g_assert(!res); + + /* Range too big (65536 is the limit against DOS attacks) */ + + v = visitor_input_test_init(data, "0-65536"); + visit_type_int64List(v, NULL, &res, &err); + error_free_or_abort(&err); + g_assert(!res); /* Empty list */ From patchwork Thu Dec 13 18:43:14 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 1013044 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43G2jl1sNpz9s4s for ; Fri, 14 Dec 2018 05:47:39 +1100 (AEDT) Received: from localhost ([::1]:54247 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXW1I-00086M-Jd for incoming@patchwork.ozlabs.org; Thu, 13 Dec 2018 13:47:36 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53113) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVxj-0005ch-7v for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:58 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXVxe-0001kq-Vi for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:54 -0500 Received: from mx1.redhat.com ([209.132.183.28]:51646) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gXVxc-0001SZ-Tl for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:49 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8B00B2D7E4 for ; Thu, 13 Dec 2018 18:43:46 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-56.ams2.redhat.com [10.36.116.56]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 70465648DC; Thu, 13 Dec 2018 18:43:43 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 58DB91138408; Thu, 13 Dec 2018 19:43:40 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2018 19:43:14 +0100 Message-Id: <20181213184340.24037-7-armbru@redhat.com> In-Reply-To: <20181213184340.24037-1-armbru@redhat.com> References: <20181213184340.24037-1-armbru@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Thu, 13 Dec 2018 18:43:46 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 06/32] qapi: Rewrite string-input-visitor's integer and list parsing X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: David Hildenbrand Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: David Hildenbrand The input visitor has some problems right now, especially - unsigned type "Range" is used to process signed ranges, resulting in inconsistent behavior and ugly/magical code - uint64_t are parsed like int64_t, so big uint64_t values are not supported and error messages are misleading - lists/ranges of int64_t are accepted although no list is parsed and we should rather report an error - lists/ranges are preparsed using int64_t, making it hard to implement uint64_t values or uint64_t lists - types that don't support lists don't bail out - visiting beyond the end of a list is not handled properly - we don't actually parse lists, we parse *sets*: members are sorted, and duplicates eliminated So let's rewrite it by getting rid of usage of the type "Range" and properly supporting lists of int64_t and uint64_t (including ranges of both types), fixing the above mentioned issues. Lists of other types are not supported and will properly report an error. Virtual walks are now supported. Tests have to be fixed up: - Two BUGs were hardcoded that are fixed now - The string-input-visitor now actually returns a parsed list and not an ordered set. Please note that no users/callers have to be fixed up. Candidates using visit_type_uint16List() and friends are: - backends/hostmem.c:host_memory_backend_set_host_nodes() -- Code can deal with duplicates/unsorted lists - numa.c::query_memdev() -- via object_property_get_uint16List(), the list will still be sorted and without duplicates (via host_memory_backend_get_host_nodes()) - qapi-visit.c::visit_type_Memdev_members() - qapi-visit.c::visit_type_NumaNodeOptions_members() - qapi-visit.c::visit_type_RockerOfDpaGroup_members - qapi-visit.c::visit_type_RxFilterInfo_members() -- Not used with string-input-visitor. Reviewed-by: Eric Blake Reviewed-by: Markus Armbruster Signed-off-by: David Hildenbrand Message-Id: <20181121164421.20780-7-david@redhat.com> Signed-off-by: Markus Armbruster --- include/qapi/string-input-visitor.h | 4 +- qapi/string-input-visitor.c | 401 ++++++++++++++++------------ tests/test-string-input-visitor.c | 18 +- 3 files changed, 232 insertions(+), 191 deletions(-) diff --git a/include/qapi/string-input-visitor.h b/include/qapi/string-input-visitor.h index 33551340e3..921f3875b9 100644 --- a/include/qapi/string-input-visitor.h +++ b/include/qapi/string-input-visitor.h @@ -19,8 +19,8 @@ typedef struct StringInputVisitor StringInputVisitor; /* * The string input visitor does not implement support for visiting - * QAPI structs, alternates, null, or arbitrary QTypes. It also - * requires a non-null list argument to visit_start_list(). + * QAPI structs, alternates, null, or arbitrary QTypes. Only flat lists + * of integers (except type "size") are supported. */ Visitor *string_input_visitor_new(const char *str); diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c index b89c6c4e06..bd92080667 100644 --- a/qapi/string-input-visitor.c +++ b/qapi/string-input-visitor.c @@ -4,10 +4,10 @@ * Copyright Red Hat, Inc. 2012-2016 * * Author: Paolo Bonzini + * David Hildenbrand * * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. * See the COPYING.LIB file in the top-level directory. - * */ #include "qemu/osdep.h" @@ -18,21 +18,42 @@ #include "qapi/qmp/qerror.h" #include "qapi/qmp/qnull.h" #include "qemu/option.h" -#include "qemu/queue.h" -#include "qemu/range.h" #include "qemu/cutils.h" +typedef enum ListMode { + /* no list parsing active / no list expected */ + LM_NONE, + /* we have an unparsed string remaining */ + LM_UNPARSED, + /* we have an unfinished int64 range */ + LM_INT64_RANGE, + /* we have an unfinished uint64 range */ + LM_UINT64_RANGE, + /* we have parsed the string completely and no range is remaining */ + LM_END, +} ListMode; + +/* protect against DOS attacks, limit the amount of elements per range */ +#define RANGE_MAX_ELEMENTS 65536 + +typedef union RangeElement { + int64_t i64; + uint64_t u64; +} RangeElement; struct StringInputVisitor { Visitor visitor; - GList *ranges; - GList *cur_range; - int64_t cur; + /* List parsing state */ + ListMode lm; + RangeElement rangeNext; + RangeElement rangeEnd; + const char *unparsed_string; + void *list; + /* The original string to parse */ const char *string; - void *list; /* Only needed for sanity checking the caller */ }; static StringInputVisitor *to_siv(Visitor *v) @@ -40,136 +61,42 @@ static StringInputVisitor *to_siv(Visitor *v) return container_of(v, StringInputVisitor, visitor); } -static void free_range(void *range, void *dummy) -{ - g_free(range); -} - -static int parse_str(StringInputVisitor *siv, const char *name, Error **errp) -{ - char *str = (char *) siv->string; - long long start, end; - Range *cur; - char *endptr; - - if (siv->ranges) { - return 0; - } - - if (!*str) { - return 0; - } - - do { - errno = 0; - start = strtoll(str, &endptr, 0); - if (errno == 0 && endptr > str) { - if (*endptr == '\0') { - cur = g_malloc0(sizeof(*cur)); - range_set_bounds(cur, start, start); - siv->ranges = range_list_insert(siv->ranges, cur); - cur = NULL; - str = NULL; - } else if (*endptr == '-') { - str = endptr + 1; - errno = 0; - end = strtoll(str, &endptr, 0); - if (errno == 0 && endptr > str && start <= end && - (start > INT64_MAX - 65536 || - end < start + 65536)) { - if (*endptr == '\0') { - cur = g_malloc0(sizeof(*cur)); - range_set_bounds(cur, start, end); - siv->ranges = range_list_insert(siv->ranges, cur); - cur = NULL; - str = NULL; - } else if (*endptr == ',') { - str = endptr + 1; - cur = g_malloc0(sizeof(*cur)); - range_set_bounds(cur, start, end); - siv->ranges = range_list_insert(siv->ranges, cur); - cur = NULL; - } else { - goto error; - } - } else { - goto error; - } - } else if (*endptr == ',') { - str = endptr + 1; - cur = g_malloc0(sizeof(*cur)); - range_set_bounds(cur, start, start); - siv->ranges = range_list_insert(siv->ranges, cur); - cur = NULL; - } else { - goto error; - } - } else { - goto error; - } - } while (str); - - return 0; -error: - g_list_foreach(siv->ranges, free_range, NULL); - g_list_free(siv->ranges); - siv->ranges = NULL; - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null", - "an int64 value or range"); - return -1; -} - -static void -start_list(Visitor *v, const char *name, GenericList **list, size_t size, - Error **errp) +static void start_list(Visitor *v, const char *name, GenericList **list, + size_t size, Error **errp) { StringInputVisitor *siv = to_siv(v); - /* We don't support visits without a list */ - assert(list); + assert(siv->lm == LM_NONE); siv->list = list; + siv->unparsed_string = siv->string; - if (parse_str(siv, name, errp) < 0) { - *list = NULL; - return; - } - - siv->cur_range = g_list_first(siv->ranges); - if (siv->cur_range) { - Range *r = siv->cur_range->data; - if (r) { - siv->cur = range_lob(r); + if (!siv->string[0]) { + if (list) { + *list = NULL; } - *list = g_malloc0(size); + siv->lm = LM_END; } else { - *list = NULL; + if (list) { + *list = g_malloc0(size); + } + siv->lm = LM_UNPARSED; } } static GenericList *next_list(Visitor *v, GenericList *tail, size_t size) { StringInputVisitor *siv = to_siv(v); - Range *r; - if (!siv->ranges || !siv->cur_range) { + switch (siv->lm) { + case LM_END: return NULL; - } - - r = siv->cur_range->data; - if (!r) { - return NULL; - } - - if (!range_contains(r, siv->cur)) { - siv->cur_range = g_list_next(siv->cur_range); - if (!siv->cur_range) { - return NULL; - } - r = siv->cur_range->data; - if (!r) { - return NULL; - } - siv->cur = range_lob(r); + case LM_INT64_RANGE: + case LM_UINT64_RANGE: + case LM_UNPARSED: + /* we have an unparsed string or something left in a range */ + break; + default: + abort(); } tail->next = g_malloc0(size); @@ -179,88 +106,208 @@ static GenericList *next_list(Visitor *v, GenericList *tail, size_t size) static void check_list(Visitor *v, Error **errp) { const StringInputVisitor *siv = to_siv(v); - Range *r; - GList *cur_range; - if (!siv->ranges || !siv->cur_range) { + switch (siv->lm) { + case LM_INT64_RANGE: + case LM_UINT64_RANGE: + case LM_UNPARSED: + error_setg(errp, "Fewer list elements expected"); return; - } - - r = siv->cur_range->data; - if (!r) { + case LM_END: return; + default: + abort(); } - - if (!range_contains(r, siv->cur)) { - cur_range = g_list_next(siv->cur_range); - if (!cur_range) { - return; - } - r = cur_range->data; - if (!r) { - return; - } - } - - error_setg(errp, "Range contains too many values"); } static void end_list(Visitor *v, void **obj) { StringInputVisitor *siv = to_siv(v); + assert(siv->lm != LM_NONE); assert(siv->list == obj); + siv->list = NULL; + siv->unparsed_string = NULL; + siv->lm = LM_NONE; +} + +static int try_parse_int64_list_entry(StringInputVisitor *siv, int64_t *obj) +{ + const char *endptr; + int64_t start, end; + + /* parse a simple int64 or range */ + if (qemu_strtoi64(siv->unparsed_string, &endptr, 0, &start)) { + return -EINVAL; + } + end = start; + + switch (endptr[0]) { + case '\0': + siv->unparsed_string = endptr; + break; + case ',': + siv->unparsed_string = endptr + 1; + break; + case '-': + /* parse the end of the range */ + if (qemu_strtoi64(endptr + 1, &endptr, 0, &end)) { + return -EINVAL; + } + if (start > end || end - start >= RANGE_MAX_ELEMENTS) { + return -EINVAL; + } + switch (endptr[0]) { + case '\0': + siv->unparsed_string = endptr; + break; + case ',': + siv->unparsed_string = endptr + 1; + break; + default: + return -EINVAL; + } + break; + default: + return -EINVAL; + } + + /* we have a proper range (with maybe only one element) */ + siv->lm = LM_INT64_RANGE; + siv->rangeNext.i64 = start; + siv->rangeEnd.i64 = end; + return 0; } static void parse_type_int64(Visitor *v, const char *name, int64_t *obj, Error **errp) { StringInputVisitor *siv = to_siv(v); + int64_t val; - if (parse_str(siv, name, errp) < 0) { + switch (siv->lm) { + case LM_NONE: + /* just parse a simple int64, bail out if not completely consumed */ + if (qemu_strtoi64(siv->string, NULL, 0, &val)) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, + name ? name : "null", "int64"); + return; + } + *obj = val; return; - } + case LM_UNPARSED: + if (try_parse_int64_list_entry(siv, obj)) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null", + "list of int64 values or ranges"); + return; + } + assert(siv->lm == LM_INT64_RANGE); + /* fall through */ + case LM_INT64_RANGE: + /* return the next element in the range */ + assert(siv->rangeNext.i64 <= siv->rangeEnd.i64); + *obj = siv->rangeNext.i64++; - if (!siv->ranges) { - goto error; + if (siv->rangeNext.i64 > siv->rangeEnd.i64 || *obj == INT64_MAX) { + /* end of range, check if there is more to parse */ + siv->lm = siv->unparsed_string[0] ? LM_UNPARSED : LM_END; + } + return; + case LM_END: + error_setg(errp, "Fewer list elements expected"); + return; + default: + abort(); } +} - if (!siv->cur_range) { - Range *r; +static int try_parse_uint64_list_entry(StringInputVisitor *siv, uint64_t *obj) +{ + const char *endptr; + uint64_t start, end; - siv->cur_range = g_list_first(siv->ranges); - if (!siv->cur_range) { - goto error; - } + /* parse a simple uint64 or range */ + if (qemu_strtou64(siv->unparsed_string, &endptr, 0, &start)) { + return -EINVAL; + } + end = start; - r = siv->cur_range->data; - if (!r) { - goto error; + switch (endptr[0]) { + case '\0': + siv->unparsed_string = endptr; + break; + case ',': + siv->unparsed_string = endptr + 1; + break; + case '-': + /* parse the end of the range */ + if (qemu_strtou64(endptr + 1, &endptr, 0, &end)) { + return -EINVAL; } - - siv->cur = range_lob(r); + if (start > end || end - start >= RANGE_MAX_ELEMENTS) { + return -EINVAL; + } + switch (endptr[0]) { + case '\0': + siv->unparsed_string = endptr; + break; + case ',': + siv->unparsed_string = endptr + 1; + break; + default: + return -EINVAL; + } + break; + default: + return -EINVAL; } - *obj = siv->cur; - siv->cur++; - return; - -error: - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null", - "an int64 value or range"); + /* we have a proper range (with maybe only one element) */ + siv->lm = LM_UINT64_RANGE; + siv->rangeNext.u64 = start; + siv->rangeEnd.u64 = end; + return 0; } static void parse_type_uint64(Visitor *v, const char *name, uint64_t *obj, Error **errp) { - /* FIXME: parse_type_int64 mishandles values over INT64_MAX */ - int64_t i; - Error *err = NULL; - parse_type_int64(v, name, &i, &err); - if (err) { - error_propagate(errp, err); - } else { - *obj = i; + StringInputVisitor *siv = to_siv(v); + uint64_t val; + + switch (siv->lm) { + case LM_NONE: + /* just parse a simple uint64, bail out if not completely consumed */ + if (qemu_strtou64(siv->string, NULL, 0, &val)) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null", + "uint64"); + return; + } + *obj = val; + return; + case LM_UNPARSED: + if (try_parse_uint64_list_entry(siv, obj)) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null", + "list of uint64 values or ranges"); + return; + } + assert(siv->lm == LM_UINT64_RANGE); + /* fall through */ + case LM_UINT64_RANGE: + /* return the next element in the range */ + assert(siv->rangeNext.u64 <= siv->rangeEnd.u64); + *obj = siv->rangeNext.u64++; + + if (siv->rangeNext.u64 > siv->rangeEnd.u64 || *obj == UINT64_MAX) { + /* end of range, check if there is more to parse */ + siv->lm = siv->unparsed_string[0] ? LM_UNPARSED : LM_END; + } + return; + case LM_END: + error_setg(errp, "Fewer list elements expected"); + return; + default: + abort(); } } @@ -271,6 +318,7 @@ static void parse_type_size(Visitor *v, const char *name, uint64_t *obj, Error *err = NULL; uint64_t val; + assert(siv->lm == LM_NONE); parse_option_size(name, siv->string, &val, &err); if (err) { error_propagate(errp, err); @@ -285,6 +333,7 @@ static void parse_type_bool(Visitor *v, const char *name, bool *obj, { StringInputVisitor *siv = to_siv(v); + assert(siv->lm == LM_NONE); if (!strcasecmp(siv->string, "on") || !strcasecmp(siv->string, "yes") || !strcasecmp(siv->string, "true")) { @@ -307,6 +356,7 @@ static void parse_type_str(Visitor *v, const char *name, char **obj, { StringInputVisitor *siv = to_siv(v); + assert(siv->lm == LM_NONE); *obj = g_strdup(siv->string); } @@ -316,6 +366,7 @@ static void parse_type_number(Visitor *v, const char *name, double *obj, StringInputVisitor *siv = to_siv(v); double val; + assert(siv->lm == LM_NONE); if (qemu_strtod_finite(siv->string, NULL, &val)) { error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", "number"); @@ -330,9 +381,10 @@ static void parse_type_null(Visitor *v, const char *name, QNull **obj, { StringInputVisitor *siv = to_siv(v); + assert(siv->lm == LM_NONE); *obj = NULL; - if (!siv->string || siv->string[0]) { + if (siv->string[0]) { error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", "null"); return; @@ -345,8 +397,6 @@ static void string_input_free(Visitor *v) { StringInputVisitor *siv = to_siv(v); - g_list_foreach(siv->ranges, free_range, NULL); - g_list_free(siv->ranges); g_free(siv); } @@ -372,5 +422,6 @@ Visitor *string_input_visitor_new(const char *str) v->visitor.free = string_input_free; v->string = str; + v->lm = LM_NONE; return &v->visitor; } diff --git a/tests/test-string-input-visitor.c b/tests/test-string-input-visitor.c index 8ee0d1b284..c5379365a6 100644 --- a/tests/test-string-input-visitor.c +++ b/tests/test-string-input-visitor.c @@ -92,16 +92,6 @@ static void check_ulist(Visitor *v, uint64_t *expected, size_t n) uint64List *tail; int i; - /* BUG: unsigned numbers above INT64_MAX don't work */ - for (i = 0; i < n; i++) { - if (expected[i] > INT64_MAX) { - Error *err = NULL; - visit_type_uint64List(v, NULL, &res, &err); - error_free_or_abort(&err); - return; - } - } - visit_type_uint64List(v, NULL, &res, &error_abort); tail = res; for (i = 0; i < n; i++) { @@ -117,10 +107,10 @@ static void check_ulist(Visitor *v, uint64_t *expected, size_t n) static void test_visitor_in_intList(TestInputVisitorData *data, const void *unused) { - /* Note: the visitor *sorts* ranges *unsigned* */ - int64_t expect1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20 }; + int64_t expect1[] = { 1, 2, 0, 2, 3, 4, 20, 5, 6, 7, + 8, 9, 1, 2, 3, 4, 5, 6, 7, 8 }; int64_t expect2[] = { 32767, -32768, -32767 }; - int64_t expect3[] = { INT64_MAX, INT64_MIN }; + int64_t expect3[] = { INT64_MIN, INT64_MAX }; int64_t expect4[] = { 1 }; uint64_t expect5[] = { UINT64_MAX }; Error *err = NULL; @@ -226,7 +216,7 @@ static void test_visitor_in_intList(TestInputVisitorData *data, visit_type_int64(v, NULL, &tail->value, &err); g_assert_cmpint(tail->value, ==, 0); visit_type_int64(v, NULL, &val, &err); - g_assert_cmpint(val, ==, 1); /* BUG */ + error_free_or_abort(&err); visit_check_list(v, &error_abort); visit_end_list(v, (void **)&res); From patchwork Thu Dec 13 18:43:16 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 1013048 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43G2nd2LjFz9s3Z for ; Fri, 14 Dec 2018 05:51:01 +1100 (AEDT) Received: from localhost ([::1]:54261 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXW4Y-0002Jr-Sy for incoming@patchwork.ozlabs.org; Thu, 13 Dec 2018 13:50:58 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53108) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVxj-0005cf-5l for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:58 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXVxe-0001jO-St for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:54 -0500 Received: from mx1.redhat.com ([209.132.183.28]:32872) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gXVxc-0001Rg-JI for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:48 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 657E3C056824 for ; Thu, 13 Dec 2018 18:43:46 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-56.ams2.redhat.com [10.36.116.56]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 4F8EE66060; Thu, 13 Dec 2018 18:43:45 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 623DE1132D34; Thu, 13 Dec 2018 19:43:40 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2018 19:43:16 +0100 Message-Id: <20181213184340.24037-9-armbru@redhat.com> In-Reply-To: <20181213184340.24037-1-armbru@redhat.com> References: <20181213184340.24037-1-armbru@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Thu, 13 Dec 2018 18:43:46 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 08/32] test-string-input-visitor: Split off uint64 list tests X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: David Hildenbrand Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: David Hildenbrand Basically copy all int64 list tests but adapt them to work on uint64 instead. The values for very big/very small values have to be adapted. Reviewed-by: Markus Armbruster Signed-off-by: David Hildenbrand Message-Id: <20181121164421.20780-9-david@redhat.com> Signed-off-by: Markus Armbruster --- tests/test-string-input-visitor.c | 113 ++++++++++++++++++++++++++++-- 1 file changed, 109 insertions(+), 4 deletions(-) diff --git a/tests/test-string-input-visitor.c b/tests/test-string-input-visitor.c index 718d9a03c3..9b1dd44b2d 100644 --- a/tests/test-string-input-visitor.c +++ b/tests/test-string-input-visitor.c @@ -112,7 +112,6 @@ static void test_visitor_in_intList(TestInputVisitorData *data, int64_t expect2[] = { 32767, -32768, -32767 }; int64_t expect3[] = { INT64_MIN, INT64_MAX }; int64_t expect4[] = { 1 }; - uint64_t expect5[] = { UINT64_MAX }; Error *err = NULL; int64List *res = NULL; Visitor *v; @@ -133,9 +132,6 @@ static void test_visitor_in_intList(TestInputVisitorData *data, v = visitor_input_test_init(data, "1-1"); check_ilist(v, expect4, ARRAY_SIZE(expect4)); - v = visitor_input_test_init(data, "18446744073709551615"); - check_ulist(v, expect5, ARRAY_SIZE(expect5)); - /* Value too large */ v = visitor_input_test_init(data, "9223372036854775808"); @@ -211,6 +207,113 @@ static void test_visitor_in_intList(TestInputVisitorData *data, visit_end_list(v, NULL); } +static void test_visitor_in_uintList(TestInputVisitorData *data, + const void *unused) +{ + uint64_t expect1[] = { 1, 2, 0, 2, 3, 4, 20, 5, 6, 7, + 8, 9, 1, 2, 3, 4, 5, 6, 7, 8 }; + uint64_t expect2[] = { 32767, -32768, -32767 }; + uint64_t expect3[] = { INT64_MIN, INT64_MAX }; + uint64_t expect4[] = { 1 }; + uint64_t expect5[] = { UINT64_MAX }; + Error *err = NULL; + uint64List *res = NULL; + Visitor *v; + uint64_t val; + + /* Valid lists */ + + v = visitor_input_test_init(data, "1,2,0,2-4,20,5-9,1-8"); + check_ulist(v, expect1, ARRAY_SIZE(expect1)); + + v = visitor_input_test_init(data, "32767,-32768--32767"); + check_ulist(v, expect2, ARRAY_SIZE(expect2)); + + v = visitor_input_test_init(data, + "-9223372036854775808,9223372036854775807"); + check_ulist(v, expect3, ARRAY_SIZE(expect3)); + + v = visitor_input_test_init(data, "1-1"); + check_ulist(v, expect4, ARRAY_SIZE(expect4)); + + v = visitor_input_test_init(data, "18446744073709551615"); + check_ulist(v, expect5, ARRAY_SIZE(expect5)); + + /* Value too large */ + + v = visitor_input_test_init(data, "18446744073709551616"); + visit_type_uint64List(v, NULL, &res, &err); + error_free_or_abort(&err); + g_assert(!res); + + /* Value too small */ + + v = visitor_input_test_init(data, "-18446744073709551616"); + visit_type_uint64List(v, NULL, &res, &err); + error_free_or_abort(&err); + g_assert(!res); + + /* Range not ascending */ + + v = visitor_input_test_init(data, "3-1"); + visit_type_uint64List(v, NULL, &res, &err); + error_free_or_abort(&err); + g_assert(!res); + + v = visitor_input_test_init(data, "18446744073709551615-0"); + visit_type_uint64List(v, NULL, &res, &err); + error_free_or_abort(&err); + g_assert(!res); + + /* Range too big (65536 is the limit against DOS attacks) */ + + v = visitor_input_test_init(data, "0-65536"); + visit_type_uint64List(v, NULL, &res, &err); + error_free_or_abort(&err); + g_assert(!res); + + /* Empty list */ + + v = visitor_input_test_init(data, ""); + visit_type_uint64List(v, NULL, &res, &error_abort); + g_assert(!res); + + /* Not a list */ + + v = visitor_input_test_init(data, "not an uint list"); + + visit_type_uint64List(v, NULL, &res, &err); + error_free_or_abort(&err); + g_assert(!res); + + /* Unvisited list tail */ + + v = visitor_input_test_init(data, "0,2-3"); + + visit_start_list(v, NULL, NULL, 0, &error_abort); + visit_type_uint64(v, NULL, &val, &error_abort); + g_assert_cmpuint(val, ==, 0); + visit_type_uint64(v, NULL, &val, &error_abort); + g_assert_cmpuint(val, ==, 2); + + visit_check_list(v, &err); + error_free_or_abort(&err); + visit_end_list(v, NULL); + + /* Visit beyond end of list */ + + v = visitor_input_test_init(data, "0"); + + visit_start_list(v, NULL, NULL, 0, &error_abort); + visit_type_uint64(v, NULL, &val, &err); + g_assert_cmpuint(val, ==, 0); + visit_type_uint64(v, NULL, &val, &err); + error_free_or_abort(&err); + + visit_check_list(v, &error_abort); + visit_end_list(v, NULL); +} + static void test_visitor_in_bool(TestInputVisitorData *data, const void *unused) { @@ -384,6 +487,8 @@ int main(int argc, char **argv) &in_visitor_data, test_visitor_in_int); input_visitor_test_add("/string-visitor/input/intList", &in_visitor_data, test_visitor_in_intList); + input_visitor_test_add("/string-visitor/input/uintList", + &in_visitor_data, test_visitor_in_uintList); input_visitor_test_add("/string-visitor/input/bool", &in_visitor_data, test_visitor_in_bool); input_visitor_test_add("/string-visitor/input/number", From patchwork Thu Dec 13 18:43:17 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 1013058 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43G2x92dmpz9s3Z for ; Fri, 14 Dec 2018 05:57:33 +1100 (AEDT) Received: from localhost ([::1]:54295 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXWAs-0008GD-Se for incoming@patchwork.ozlabs.org; Thu, 13 Dec 2018 13:57:30 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53320) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVxv-0005pl-I9 for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:08 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXVxr-0002i5-Kt for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:05 -0500 Received: from mx1.redhat.com ([209.132.183.28]:39508) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gXVxo-0001OY-H2 for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:01 -0500 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A40B881129 for ; Thu, 13 Dec 2018 18:43:45 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-56.ams2.redhat.com [10.36.116.56]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 713FB5D756; Thu, 13 Dec 2018 18:43:45 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 672F31132D3B; Thu, 13 Dec 2018 19:43:40 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2018 19:43:17 +0100 Message-Id: <20181213184340.24037-10-armbru@redhat.com> In-Reply-To: <20181213184340.24037-1-armbru@redhat.com> References: <20181213184340.24037-1-armbru@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Thu, 13 Dec 2018 18:43:45 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 09/32] test-string-input-visitor: Add range overflow tests X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: David Hildenbrand Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: David Hildenbrand Let's make sure that the range handling code can properly deal with ranges that end at the biggest possible number. Reviewed-by: Markus Armbruster Signed-off-by: David Hildenbrand Message-Id: <20181121164421.20780-10-david@redhat.com> Signed-off-by: Markus Armbruster --- tests/test-string-input-visitor.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/test-string-input-visitor.c b/tests/test-string-input-visitor.c index 9b1dd44b2d..34b54dfc89 100644 --- a/tests/test-string-input-visitor.c +++ b/tests/test-string-input-visitor.c @@ -112,6 +112,7 @@ static void test_visitor_in_intList(TestInputVisitorData *data, int64_t expect2[] = { 32767, -32768, -32767 }; int64_t expect3[] = { INT64_MIN, INT64_MAX }; int64_t expect4[] = { 1 }; + int64_t expect5[] = { INT64_MAX - 2, INT64_MAX - 1, INT64_MAX }; Error *err = NULL; int64List *res = NULL; Visitor *v; @@ -132,6 +133,10 @@ static void test_visitor_in_intList(TestInputVisitorData *data, v = visitor_input_test_init(data, "1-1"); check_ilist(v, expect4, ARRAY_SIZE(expect4)); + v = visitor_input_test_init(data, + "9223372036854775805-9223372036854775807"); + check_ilist(v, expect5, ARRAY_SIZE(expect5)); + /* Value too large */ v = visitor_input_test_init(data, "9223372036854775808"); @@ -216,6 +221,7 @@ static void test_visitor_in_uintList(TestInputVisitorData *data, uint64_t expect3[] = { INT64_MIN, INT64_MAX }; uint64_t expect4[] = { 1 }; uint64_t expect5[] = { UINT64_MAX }; + uint64_t expect6[] = { UINT64_MAX - 2, UINT64_MAX - 1, UINT64_MAX }; Error *err = NULL; uint64List *res = NULL; Visitor *v; @@ -239,6 +245,10 @@ static void test_visitor_in_uintList(TestInputVisitorData *data, v = visitor_input_test_init(data, "18446744073709551615"); check_ulist(v, expect5, ARRAY_SIZE(expect5)); + v = visitor_input_test_init(data, + "18446744073709551613-18446744073709551615"); + check_ulist(v, expect6, ARRAY_SIZE(expect6)); + /* Value too large */ v = visitor_input_test_init(data, "18446744073709551616"); From patchwork Thu Dec 13 18:43:18 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 1013051 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43G2rP4WCRz9s3Z for ; Fri, 14 Dec 2018 05:53:25 +1100 (AEDT) Received: from localhost ([::1]:54274 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXW6t-0004Of-65 for incoming@patchwork.ozlabs.org; Thu, 13 Dec 2018 13:53:23 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53264) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVxr-0005l6-KL for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:04 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXVxn-0002RU-Qx for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:01 -0500 Received: from mx1.redhat.com ([209.132.183.28]:36604) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gXVxl-0001P6-Vz for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:58 -0500 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B2FB5307D844 for ; Thu, 13 Dec 2018 18:43:45 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-56.ams2.redhat.com [10.36.116.56]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 7A9311992A; Thu, 13 Dec 2018 18:43:45 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 6C15A1132D3E; Thu, 13 Dec 2018 19:43:40 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2018 19:43:18 +0100 Message-Id: <20181213184340.24037-11-armbru@redhat.com> In-Reply-To: <20181213184340.24037-1-armbru@redhat.com> References: <20181213184340.24037-1-armbru@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.48]); Thu, 13 Dec 2018 18:43:45 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 10/32] docs: Update references to JSON RFC X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 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" From: Eric Blake RFC8259 obsoletes RFC7159. Fix a couple of URLs to point to the newer version. Signed-off-by: Eric Blake Message-Id: <20181203175702.128701-1-eblake@redhat.com> Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster --- docs/devel/qapi-code-gen.txt | 2 +- docs/interop/qmp-spec.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt index 53eaf01f34..2c8b392b20 100644 --- a/docs/devel/qapi-code-gen.txt +++ b/docs/devel/qapi-code-gen.txt @@ -26,7 +26,7 @@ how the schemas, scripts, and resulting code are used. == QMP/Guest agent schema == A QAPI schema file is designed to be loosely based on JSON -(http://www.ietf.org/rfc/rfc7159.txt) with changes for quoting style +(http://www.ietf.org/rfc/rfc8259.txt) with changes for quoting style and the use of comments; a QAPI schema file is then parsed by a python code generation program. A valid QAPI schema consists of a series of top-level expressions, with no commas between them. Where diff --git a/docs/interop/qmp-spec.txt b/docs/interop/qmp-spec.txt index 67e44a8120..adcf86754d 100644 --- a/docs/interop/qmp-spec.txt +++ b/docs/interop/qmp-spec.txt @@ -32,7 +32,7 @@ following format: Where DATA-STRUCTURE-NAME is any valid JSON data structure, as defined by the JSON standard: -http://www.ietf.org/rfc/rfc7159.txt +http://www.ietf.org/rfc/rfc8259.txt The server expects its input to be encoded in UTF-8, and sends its output encoded in ASCII. From patchwork Thu Dec 13 18:43:19 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 1013056 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43G2vr2gLXz9s3Z for ; Fri, 14 Dec 2018 05:56:24 +1100 (AEDT) Received: from localhost ([::1]:54291 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXW9l-0007Mq-OX for incoming@patchwork.ozlabs.org; Thu, 13 Dec 2018 13:56:21 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53375) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVy6-00061l-7U for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:18 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXVxv-0002yj-Iu for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:12 -0500 Received: from mx1.redhat.com ([209.132.183.28]:43102) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gXVxr-0001PZ-Mc for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:05 -0500 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E54FC308FF0C for ; Thu, 13 Dec 2018 18:43:45 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-56.ams2.redhat.com [10.36.116.56]) by smtp.corp.redhat.com (Postfix) with ESMTPS id B32284530 for ; Thu, 13 Dec 2018 18:43:45 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 716141132CA2; Thu, 13 Dec 2018 19:43:40 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2018 19:43:19 +0100 Message-Id: <20181213184340.24037-12-armbru@redhat.com> In-Reply-To: <20181213184340.24037-1-armbru@redhat.com> References: <20181213184340.24037-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.49]); Thu, 13 Dec 2018 18:43:45 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 11/32] json: Fix to reject duplicate object member names X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 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" The JSON parser happily accepts duplicate object member names. The last value wins. Reproducer #1: $ qemu-system-x86_64 -qmp stdio {"QMP": {"version": {"qemu": {"micro": 93, "minor": 0, "major": 3}, "package": "v3.1.0-rc3-7-g87a45d86ed"}, "capabilities": []}} {'execute':'qmp_capabilities'} {"return": {}} {'execute':'blockdev-add','arguments':{'driver':'null-co', 'node-name':'foo','node-name':'bar'}} {"return": {}} {'execute':'query-named-block-nodes'} {"return": [{ [...] "node-name": "bar" [...] }]} Reproducer #2 is iotest 229. Fix the parser to reject duplicates, and fix iotest 229 not to use them. Reported-by: Max Reitz Signed-off-by: Markus Armbruster Message-Id: <20181206121743.20762-1-armbru@redhat.com> Reviewed-by: Daniel P. Berrangé Reviewed-by: Philippe Mathieu-Daudé [Trailing whitespace tidied up] Signed-off-by: Markus Armbruster --- qobject/json-parser.c | 5 +++++ tests/qemu-iotests/229 | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/qobject/json-parser.c b/qobject/json-parser.c index 5a840dfd86..7a7ae9e8d1 100644 --- a/qobject/json-parser.c +++ b/qobject/json-parser.c @@ -288,6 +288,11 @@ static int parse_pair(JSONParserContext *ctxt, QDict *dict) goto out; } + if (qdict_haskey(dict, qstring_get_str(key))) { + parse_error(ctxt, token, "duplicate key"); + goto out; + } + qdict_put_obj(dict, qstring_get_str(key), value); qobject_unref(key); diff --git a/tests/qemu-iotests/229 b/tests/qemu-iotests/229 index 86602437ff..893d098ad2 100755 --- a/tests/qemu-iotests/229 +++ b/tests/qemu-iotests/229 @@ -69,7 +69,6 @@ echo _send_qemu_cmd $QEMU_HANDLE \ "{'execute': 'drive-mirror', 'arguments': {'device': 'testdisk', - 'mode': 'absolute-paths', 'format': '$IMGFMT', 'target': '$DEST_IMG', 'sync': 'full', From patchwork Thu Dec 13 18:43:20 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 1013054 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43G2t63KKXz9s3Z for ; Fri, 14 Dec 2018 05:54:52 +1100 (AEDT) Received: from localhost ([::1]:54280 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXW8H-000689-4f for incoming@patchwork.ozlabs.org; Thu, 13 Dec 2018 13:54:49 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53201) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVxo-0005hc-Hi for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:02 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXVxj-000279-76 for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:59 -0500 Received: from mx1.redhat.com ([209.132.183.28]:41454) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gXVxe-0001ZT-Tq for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:54 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6D28D8830E for ; Thu, 13 Dec 2018 18:43:48 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-56.ams2.redhat.com [10.36.116.56]) by smtp.corp.redhat.com (Postfix) with ESMTPS id B879861496; Thu, 13 Dec 2018 18:43:45 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 771721132CC1; Thu, 13 Dec 2018 19:43:40 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2018 19:43:20 +0100 Message-Id: <20181213184340.24037-13-armbru@redhat.com> In-Reply-To: <20181213184340.24037-1-armbru@redhat.com> References: <20181213184340.24037-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Thu, 13 Dec 2018 18:43:48 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 12/32] tests/qapi: Cover commands with 'if' and union / alternate 'data' X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Forgotten in commit 967c885108f. Signed-off-by: Marc-André Lureau Message-Id: <20181208111606.8505-19-marcandre.lureau@redhat.com> Message-Id: <20181208111606.8505-21-marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster [Squashed, commit message adjusted] Signed-off-by: Markus Armbruster --- tests/qapi-schema/qapi-schema-test.json | 6 ++++++ tests/qapi-schema/qapi-schema-test.out | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json index fb03163430..15388ae9a4 100644 --- a/tests/qapi-schema/qapi-schema-test.json +++ b/tests/qapi-schema/qapi-schema-test.json @@ -210,9 +210,15 @@ { 'union': 'TestIfUnion', 'data': { 'foo': 'TestStruct' }, 'if': 'defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)' } +{ 'command': 'TestIfUnionCmd', 'data': { 'union_cmd_arg': 'TestIfUnion' }, + 'if': 'defined(TEST_IF_UNION)' } + { 'alternate': 'TestIfAlternate', 'data': { 'foo': 'int', 'bar': 'TestStruct' }, 'if': 'defined(TEST_IF_ALT) && defined(TEST_IF_STRUCT)' } +{ 'command': 'TestIfAlternateCmd', 'data': { 'alt_cmd_arg': 'TestIfAlternate' }, + 'if': 'defined(TEST_IF_ALT)' } + { 'command': 'TestIfCmd', 'data': { 'foo': 'TestIfStruct' }, 'returns': 'UserDefThree', 'if': ['defined(TEST_IF_CMD)', 'defined(TEST_IF_STRUCT)'] } diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out index 218ac7d556..3ca858dd0e 100644 --- a/tests/qapi-schema/qapi-schema-test.out +++ b/tests/qapi-schema/qapi-schema-test.out @@ -251,11 +251,23 @@ object TestIfUnion tag type case foo: q_obj_TestStruct-wrapper if ['defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)'] +object q_obj_TestIfUnionCmd-arg + member union_cmd_arg: TestIfUnion optional=False + if ['defined(TEST_IF_UNION)'] +command TestIfUnionCmd q_obj_TestIfUnionCmd-arg -> None + gen=True success_response=True boxed=False oob=False preconfig=False + if ['defined(TEST_IF_UNION)'] alternate TestIfAlternate tag type case foo: int case bar: TestStruct if ['defined(TEST_IF_ALT) && defined(TEST_IF_STRUCT)'] +object q_obj_TestIfAlternateCmd-arg + member alt_cmd_arg: TestIfAlternate optional=False + if ['defined(TEST_IF_ALT)'] +command TestIfAlternateCmd q_obj_TestIfAlternateCmd-arg -> None + gen=True success_response=True boxed=False oob=False preconfig=False + if ['defined(TEST_IF_ALT)'] object q_obj_TestIfCmd-arg member foo: TestIfStruct optional=False if ['defined(TEST_IF_CMD)', 'defined(TEST_IF_STRUCT)'] From patchwork Thu Dec 13 18:43:21 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 1013047 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43G2lB24m8z9s9G for ; Fri, 14 Dec 2018 05:48:54 +1100 (AEDT) Received: from localhost ([::1]:54253 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXW2V-0000gr-Nk for incoming@patchwork.ozlabs.org; Thu, 13 Dec 2018 13:48:51 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53190) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVxo-0005hV-GX for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:02 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXVxl-0002Iu-Rx for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:59 -0500 Received: from mx1.redhat.com ([209.132.183.28]:34298) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gXVxj-0001cg-Ok for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:56 -0500 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A48D23082204 for ; Thu, 13 Dec 2018 18:43:48 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-56.ams2.redhat.com [10.36.116.56]) by smtp.corp.redhat.com (Postfix) with ESMTPS id BE8EE600C5; Thu, 13 Dec 2018 18:43:45 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 7BB211132CC9; Thu, 13 Dec 2018 19:43:40 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2018 19:43:21 +0100 Message-Id: <20181213184340.24037-14-armbru@redhat.com> In-Reply-To: <20181213184340.24037-1-armbru@redhat.com> References: <20181213184340.24037-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.47]); Thu, 13 Dec 2018 18:43:48 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 13/32] qapi: rename QAPISchemaEnumType.values to .members X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Rename QAPISchemaEnumType.values and related variables to members. Makes sense ever since commit 93bda4dd4 changed .values from list of string to list of QAPISchemaMember. Obvious no-op. Signed-off-by: Marc-André Lureau Reviewed-by: Markus Armbruster Message-Id: <20181208111606.8505-4-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster --- scripts/qapi/common.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index 7b62a4c7b0..046b7e5681 100644 --- a/scripts/qapi/common.py +++ b/scripts/qapi/common.py @@ -1161,22 +1161,22 @@ class QAPISchemaBuiltinType(QAPISchemaType): class QAPISchemaEnumType(QAPISchemaType): - def __init__(self, name, info, doc, ifcond, values, prefix): + def __init__(self, name, info, doc, ifcond, members, prefix): QAPISchemaType.__init__(self, name, info, doc, ifcond) - for v in values: - assert isinstance(v, QAPISchemaMember) - v.set_owner(name) + for m in members: + assert isinstance(m, QAPISchemaMember) + m.set_owner(name) assert prefix is None or isinstance(prefix, str) - self.values = values + self.members = members self.prefix = prefix def check(self, schema): QAPISchemaType.check(self, schema) seen = {} - for v in self.values: - v.check_clash(self.info, seen) + for m in self.members: + m.check_clash(self.info, seen) if self.doc: - self.doc.connect_member(v) + self.doc.connect_member(m) def is_implicit(self): # See QAPISchema._make_implicit_enum_type() and ._def_predefineds() @@ -1186,7 +1186,7 @@ class QAPISchemaEnumType(QAPISchemaType): return c_name(self.name) def member_names(self): - return [v.name for v in self.values] + return [m.name for m in self.members] def json_type(self): return 'string' @@ -1403,9 +1403,9 @@ class QAPISchemaObjectTypeVariants(object): if self._tag_name: # flat union # branches that are not explicitly covered get an empty type cases = set([v.name for v in self.variants]) - for val in self.tag_member.type.values: - if val.name not in cases: - v = QAPISchemaObjectTypeVariant(val.name, 'q_empty') + for m in self.tag_member.type.members: + if m.name not in cases: + v = QAPISchemaObjectTypeVariant(m.name, 'q_empty') v.set_owner(self.tag_member.owner) self.variants.append(v) for v in self.variants: From patchwork Thu Dec 13 18:43:22 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 1013053 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43G2sh1v5Bz9s3Z for ; Fri, 14 Dec 2018 05:54:32 +1100 (AEDT) Received: from localhost ([::1]:54278 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXW7x-0005ru-6N for incoming@patchwork.ozlabs.org; Thu, 13 Dec 2018 13:54:29 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53275) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVxr-0005lG-Or for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:07 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXVxn-0002Rh-TK for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:03 -0500 Received: from mx1.redhat.com ([209.132.183.28]:34300) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gXVxm-0001d7-03 for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:58 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id BBAC73082211 for ; Thu, 13 Dec 2018 18:43:48 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-56.ams2.redhat.com [10.36.116.56]) by smtp.corp.redhat.com (Postfix) with ESMTPS id C666E61B7E; Thu, 13 Dec 2018 18:43:45 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 8072A1132C03; Thu, 13 Dec 2018 19:43:40 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2018 19:43:22 +0100 Message-Id: <20181213184340.24037-15-armbru@redhat.com> In-Reply-To: <20181213184340.24037-1-armbru@redhat.com> References: <20181213184340.24037-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.47]); Thu, 13 Dec 2018 18:43:48 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 14/32] qapi: break long lines at 'data' member X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Let's break the line before 'data'. While at it, improve a bit indentation/spacing. (I removed some alignment which are not helping much readability and become quickly inconsistent) Suggested-by: Markus Armbruster Signed-off-by: Marc-André Lureau Message-Id: <20181208111606.8505-26-marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster --- qapi/block-core.json | 13 ++-- qapi/char.json | 138 +++++++++++++++++++++++++------------------ qapi/migration.json | 3 +- qapi/misc.json | 7 ++- qapi/net.json | 3 +- qapi/tpm.json | 5 +- qapi/ui.json | 3 +- 7 files changed, 101 insertions(+), 71 deletions(-) diff --git a/qapi/block-core.json b/qapi/block-core.json index d4fe710836..92e0205d91 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -1143,8 +1143,10 @@ # This command is now obsolete and will always return an error since 2.10 # ## -{ 'command': 'block_passwd', 'data': {'*device': 'str', - '*node-name': 'str', 'password': 'str'} } +{ 'command': 'block_passwd', + 'data': { '*device': 'str', + '*node-name': 'str', + 'password': 'str' } } ## # @block_resize: @@ -1171,9 +1173,10 @@ # <- { "return": {} } # ## -{ 'command': 'block_resize', 'data': { '*device': 'str', - '*node-name': 'str', - 'size': 'int' }} +{ 'command': 'block_resize', + 'data': { '*device': 'str', + '*node-name': 'str', + 'size': 'int' } } ## # @NewImageMode: diff --git a/qapi/char.json b/qapi/char.json index 79bac598a0..24628331ec 100644 --- a/qapi/char.json +++ b/qapi/char.json @@ -25,9 +25,10 @@ # # Since: 0.14.0 ## -{ 'struct': 'ChardevInfo', 'data': {'label': 'str', - 'filename': 'str', - 'frontend-open': 'bool'} } +{ 'struct': 'ChardevInfo', + 'data': { 'label': 'str', + 'filename': 'str', + 'frontend-open': 'bool' } } ## # @query-chardev: @@ -152,7 +153,8 @@ # ## { 'command': 'ringbuf-write', - 'data': {'device': 'str', 'data': 'str', + 'data': { 'device': 'str', + 'data': 'str', '*format': 'DataFormat'} } ## @@ -202,8 +204,9 @@ # # Since: 2.6 ## -{ 'struct': 'ChardevCommon', 'data': { '*logfile': 'str', - '*logappend': 'bool' } } +{ 'struct': 'ChardevCommon', + 'data': { '*logfile': 'str', + '*logappend': 'bool' } } ## # @ChardevFile: @@ -217,9 +220,10 @@ # # Since: 1.4 ## -{ 'struct': 'ChardevFile', 'data': { '*in' : 'str', - 'out' : 'str', - '*append': 'bool' }, +{ 'struct': 'ChardevFile', + 'data': { '*in': 'str', + 'out': 'str', + '*append': 'bool' }, 'base': 'ChardevCommon' } ## @@ -232,7 +236,8 @@ # # Since: 1.4 ## -{ 'struct': 'ChardevHostdev', 'data': { 'device' : 'str' }, +{ 'struct': 'ChardevHostdev', + 'data': { 'device': 'str' }, 'base': 'ChardevCommon' } ## @@ -260,15 +265,16 @@ # # Since: 1.4 ## -{ 'struct': 'ChardevSocket', 'data': { 'addr' : 'SocketAddressLegacy', - '*tls-creds' : 'str', - '*server' : 'bool', - '*wait' : 'bool', - '*nodelay' : 'bool', - '*telnet' : 'bool', - '*tn3270' : 'bool', - '*websocket' : 'bool', - '*reconnect' : 'int' }, +{ 'struct': 'ChardevSocket', + 'data': { 'addr': 'SocketAddressLegacy', + '*tls-creds': 'str', + '*server': 'bool', + '*wait': 'bool', + '*nodelay': 'bool', + '*telnet': 'bool', + '*tn3270': 'bool', + '*websocket': 'bool', + '*reconnect': 'int' }, 'base': 'ChardevCommon' } ## @@ -281,8 +287,9 @@ # # Since: 1.5 ## -{ 'struct': 'ChardevUdp', 'data': { 'remote' : 'SocketAddressLegacy', - '*local' : 'SocketAddressLegacy' }, +{ 'struct': 'ChardevUdp', + 'data': { 'remote': 'SocketAddressLegacy', + '*local': 'SocketAddressLegacy' }, 'base': 'ChardevCommon' } ## @@ -294,7 +301,8 @@ # # Since: 1.5 ## -{ 'struct': 'ChardevMux', 'data': { 'chardev' : 'str' }, +{ 'struct': 'ChardevMux', + 'data': { 'chardev': 'str' }, 'base': 'ChardevCommon' } ## @@ -308,7 +316,8 @@ # # Since: 1.5 ## -{ 'struct': 'ChardevStdio', 'data': { '*signal' : 'bool' }, +{ 'struct': 'ChardevStdio', + 'data': { '*signal': 'bool' }, 'base': 'ChardevCommon' } @@ -321,7 +330,8 @@ # # Since: 1.5 ## -{ 'struct': 'ChardevSpiceChannel', 'data': { 'type' : 'str' }, +{ 'struct': 'ChardevSpiceChannel', + 'data': { 'type': 'str' }, 'base': 'ChardevCommon' } # TODO: 'if': 'defined(CONFIG_SPICE)' @@ -334,7 +344,8 @@ # # Since: 1.5 ## -{ 'struct': 'ChardevSpicePort', 'data': { 'fqdn' : 'str' }, +{ 'struct': 'ChardevSpicePort', + 'data': { 'fqdn': 'str' }, 'base': 'ChardevCommon' } # TODO: 'if': 'defined(CONFIG_SPICE)' @@ -350,10 +361,11 @@ # # Since: 1.5 ## -{ 'struct': 'ChardevVC', 'data': { '*width' : 'int', - '*height' : 'int', - '*cols' : 'int', - '*rows' : 'int' }, +{ 'struct': 'ChardevVC', + 'data': { '*width': 'int', + '*height': 'int', + '*cols': 'int', + '*rows': 'int' }, 'base': 'ChardevCommon' } ## @@ -365,7 +377,8 @@ # # Since: 1.5 ## -{ 'struct': 'ChardevRingbuf', 'data': { '*size' : 'int' }, +{ 'struct': 'ChardevRingbuf', + 'data': { '*size': 'int' }, 'base': 'ChardevCommon' } ## @@ -375,29 +388,30 @@ # # Since: 1.4 (testdev since 2.2, wctablet since 2.9) ## -{ 'union': 'ChardevBackend', 'data': { 'file' : 'ChardevFile', - 'serial' : 'ChardevHostdev', - 'parallel': 'ChardevHostdev', - 'pipe' : 'ChardevHostdev', - 'socket' : 'ChardevSocket', - 'udp' : 'ChardevUdp', - 'pty' : 'ChardevCommon', - 'null' : 'ChardevCommon', - 'mux' : 'ChardevMux', - 'msmouse': 'ChardevCommon', - 'wctablet' : 'ChardevCommon', - 'braille': 'ChardevCommon', - 'testdev': 'ChardevCommon', - 'stdio' : 'ChardevStdio', - 'console': 'ChardevCommon', - 'spicevmc': 'ChardevSpiceChannel', +{ 'union': 'ChardevBackend', + 'data': { 'file': 'ChardevFile', + 'serial': 'ChardevHostdev', + 'parallel': 'ChardevHostdev', + 'pipe': 'ChardevHostdev', + 'socket': 'ChardevSocket', + 'udp': 'ChardevUdp', + 'pty': 'ChardevCommon', + 'null': 'ChardevCommon', + 'mux': 'ChardevMux', + 'msmouse': 'ChardevCommon', + 'wctablet': 'ChardevCommon', + 'braille': 'ChardevCommon', + 'testdev': 'ChardevCommon', + 'stdio': 'ChardevStdio', + 'console': 'ChardevCommon', + 'spicevmc': 'ChardevSpiceChannel', # TODO: { 'type': 'ChardevSpiceChannel', 'if': 'defined(CONFIG_SPICE)' }, - 'spiceport': 'ChardevSpicePort', + 'spiceport': 'ChardevSpicePort', # TODO: { 'type': 'ChardevSpicePort', 'if': 'defined(CONFIG_SPICE)' }, - 'vc' : 'ChardevVC', - 'ringbuf': 'ChardevRingbuf', - # next one is just for compatibility - 'memory' : 'ChardevRingbuf' } } + 'vc': 'ChardevVC', + 'ringbuf': 'ChardevRingbuf', + # next one is just for compatibility + 'memory': 'ChardevRingbuf' } } ## # @ChardevReturn: @@ -409,7 +423,8 @@ # # Since: 1.4 ## -{ 'struct' : 'ChardevReturn', 'data': { '*pty' : 'str' } } +{ 'struct' : 'ChardevReturn', + 'data': { '*pty': 'str' } } ## # @chardev-add: @@ -442,8 +457,9 @@ # <- { "return": { "pty" : "/dev/pty/42" } } # ## -{ 'command': 'chardev-add', 'data': {'id' : 'str', - 'backend' : 'ChardevBackend' }, +{ 'command': 'chardev-add', + 'data': { 'id': 'str', + 'backend': 'ChardevBackend' }, 'returns': 'ChardevReturn' } ## @@ -482,8 +498,9 @@ # <- {"return": {}} # ## -{ 'command': 'chardev-change', 'data': {'id' : 'str', - 'backend' : 'ChardevBackend' }, +{ 'command': 'chardev-change', + 'data': { 'id': 'str', + 'backend': 'ChardevBackend' }, 'returns': 'ChardevReturn' } ## @@ -503,7 +520,8 @@ # <- { "return": {} } # ## -{ 'command': 'chardev-remove', 'data': {'id': 'str'} } +{ 'command': 'chardev-remove', + 'data': { 'id': 'str' } } ## # @chardev-send-break: @@ -522,7 +540,8 @@ # <- { "return": {} } # ## -{ 'command': 'chardev-send-break', 'data': {'id': 'str'} } +{ 'command': 'chardev-send-break', + 'data': { 'id': 'str' } } ## # @VSERPORT_CHANGE: @@ -543,4 +562,5 @@ # ## { 'event': 'VSERPORT_CHANGE', - 'data': { 'id': 'str', 'open': 'bool' } } + 'data': { 'id': 'str', + 'open': 'bool' } } diff --git a/qapi/migration.json b/qapi/migration.json index 38d4c41d88..5fd33316a0 100644 --- a/qapi/migration.json +++ b/qapi/migration.json @@ -1356,7 +1356,8 @@ # # Since: 3.0 ## -{ 'command': 'migrate-recover', 'data': { 'uri': 'str' }, +{ 'command': 'migrate-recover', + 'data': { 'uri': 'str' }, 'allow-oob': true } ## diff --git a/qapi/misc.json b/qapi/misc.json index 4211a732f3..8325e0dc9c 100644 --- a/qapi/misc.json +++ b/qapi/misc.json @@ -2385,7 +2385,9 @@ # <- { "return": { "fdset-id": 1, "fd": 3 } } # ## -{ 'command': 'add-fd', 'data': {'*fdset-id': 'int', '*opaque': 'str'}, +{ 'command': 'add-fd', + 'data': { '*fdset-id': 'int', + '*opaque': 'str' }, 'returns': 'AddfdInfo' } ## @@ -2657,7 +2659,8 @@ # } # ## -{'command': 'query-command-line-options', 'data': { '*option': 'str' }, +{'command': 'query-command-line-options', + 'data': { '*option': 'str' }, 'returns': ['CommandLineOptionInfo'], 'allow-preconfig': true } diff --git a/qapi/net.json b/qapi/net.json index 8f99fd911d..a1a0f39f74 100644 --- a/qapi/net.json +++ b/qapi/net.json @@ -657,7 +657,8 @@ # } # ## -{ 'command': 'query-rx-filter', 'data': { '*name': 'str' }, +{ 'command': 'query-rx-filter', + 'data': { '*name': 'str' }, 'returns': ['RxFilterInfo'] } ## diff --git a/qapi/tpm.json b/qapi/tpm.json index d50deef5e9..b30323bb6b 100644 --- a/qapi/tpm.json +++ b/qapi/tpm.json @@ -76,8 +76,9 @@ # # Since: 1.5 ## -{ 'struct': 'TPMPassthroughOptions', 'data': { '*path' : 'str', - '*cancel-path' : 'str'} } +{ 'struct': 'TPMPassthroughOptions', + 'data': { '*path': 'str', + '*cancel-path': 'str' } } ## # @TPMEmulatorOptions: diff --git a/qapi/ui.json b/qapi/ui.json index fd39acb5c3..5ad13248d5 100644 --- a/qapi/ui.json +++ b/qapi/ui.json @@ -598,7 +598,8 @@ # Notes: An empty password in this command will set the password to the empty # string. Existing clients are unaffected by executing this command. ## -{ 'command': 'change-vnc-password', 'data': {'password': 'str'}, +{ 'command': 'change-vnc-password', + 'data': { 'password': 'str' }, 'if': 'defined(CONFIG_VNC)' } ## From patchwork Thu Dec 13 18:43:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 1013050 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43G2pT4Ztpz9s3Z for ; Fri, 14 Dec 2018 05:51:45 +1100 (AEDT) Received: from localhost ([::1]:54268 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXW5H-0002rv-8F for incoming@patchwork.ozlabs.org; Thu, 13 Dec 2018 13:51:43 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53193) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVxo-0005hY-Go for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXVxl-0002Ip-Rw for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:59 -0500 Received: from mx1.redhat.com ([209.132.183.28]:33508) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gXVxj-0001eR-Od for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:56 -0500 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 73EB588E50 for ; Thu, 13 Dec 2018 18:43:49 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-56.ams2.redhat.com [10.36.116.56]) by smtp.corp.redhat.com (Postfix) with ESMTPS id BA68260BE7; Thu, 13 Dec 2018 18:43:46 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 84A4A1132C04; Thu, 13 Dec 2018 19:43:40 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2018 19:43:23 +0100 Message-Id: <20181213184340.24037-16-armbru@redhat.com> In-Reply-To: <20181213184340.24037-1-armbru@redhat.com> References: <20181213184340.24037-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Thu, 13 Dec 2018 18:43:49 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 15/32] qapi: Do not define enumeration value explicitly X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau The generated C enumeration types explicitly set the enumeration constants to 0, 1, 2, ... That's exactly what you get when you don't supply values. Drop the explicit values. No change now, but it will avoid gaps in the values when we later add support for 'if' conditions. Avoiding such gaps will save us the trouble of changing the ENUM_lookup[] tables to work without a sentinel. We'll have to take care to ensure the headers required by the 'if' conditions get always included before the generated QAPI code. Fortunately, our convention to include "qemu/osdep.h" first in any .c ensures that's the case for our CONFIG_FOO macros. Signed-off-by: Marc-André Lureau Reviewed-by: Markus Armbruster Message-Id: <20181213123724.4866-2-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster --- scripts/qapi/common.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index 046b7e5681..55c914ec44 100644 --- a/scripts/qapi/common.py +++ b/scripts/qapi/common.py @@ -2045,14 +2045,11 @@ typedef enum %(c_name)s { ''', c_name=c_name(name)) - i = 0 for value in enum_values: ret += mcgen(''' - %(c_enum)s = %(i)d, + %(c_enum)s, ''', - c_enum=c_enum_const(name, value, prefix), - i=i) - i += 1 + c_enum=c_enum_const(name, value, prefix)) ret += mcgen(''' } %(c_name)s; From patchwork Thu Dec 13 18:43:24 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 1013078 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43G3Bt3WGlz9s3Z for ; Fri, 14 Dec 2018 06:09:26 +1100 (AEDT) Received: from localhost ([::1]:54369 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXWMN-0002NE-Qq for incoming@patchwork.ozlabs.org; Thu, 13 Dec 2018 14:09:23 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53392) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVy7-00062H-1g for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:20 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXVxx-00036U-9K for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:14 -0500 Received: from mx1.redhat.com ([209.132.183.28]:59762) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gXVxr-0001oq-N3 for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:05 -0500 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 63B253002511 for ; Thu, 13 Dec 2018 18:43:51 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-56.ams2.redhat.com [10.36.116.56]) by smtp.corp.redhat.com (Postfix) with ESMTPS id C221F1974F; Thu, 13 Dec 2018 18:43:46 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 88C2B1132C05; Thu, 13 Dec 2018 19:43:40 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2018 19:43:24 +0100 Message-Id: <20181213184340.24037-17-armbru@redhat.com> In-Reply-To: <20181213184340.24037-1-armbru@redhat.com> References: <20181213184340.24037-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.45]); Thu, 13 Dec 2018 18:43:51 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 16/32] qapi: change enum visitor and gen_enum* to take QAPISchemaMember X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau This will allow to add and access more properties associated with enum values/members, like the associated 'if' condition. We may want to have a specialized type QAPISchemaEnumMember, for now this will do. Modify gen_enum() and gen_enum_lookup() for the same reason. Suggested-by: Markus Armbruster Signed-off-by: Marc-André Lureau Reviewed-by: Markus Armbruster Message-Id: <20181213123724.4866-3-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster --- scripts/qapi/common.py | 22 +++++++++++----------- scripts/qapi/doc.py | 2 +- scripts/qapi/events.py | 13 +++++++------ scripts/qapi/introspect.py | 5 +++-- scripts/qapi/types.py | 6 +++--- scripts/qapi/visit.py | 2 +- tests/qapi-schema/test-qapi.py | 4 ++-- 7 files changed, 28 insertions(+), 26 deletions(-) diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index 55c914ec44..1fa2f79990 100644 --- a/scripts/qapi/common.py +++ b/scripts/qapi/common.py @@ -1063,7 +1063,7 @@ class QAPISchemaVisitor(object): def visit_builtin_type(self, name, info, json_type): pass - def visit_enum_type(self, name, info, ifcond, values, prefix): + def visit_enum_type(self, name, info, ifcond, members, prefix): pass def visit_array_type(self, name, info, ifcond, element_type): @@ -1193,7 +1193,7 @@ class QAPISchemaEnumType(QAPISchemaType): def visit(self, visitor): visitor.visit_enum_type(self.name, self.info, self.ifcond, - self.member_names(), self.prefix) + self.members, self.prefix) class QAPISchemaArrayType(QAPISchemaType): @@ -2012,19 +2012,19 @@ def _wrap_ifcond(ifcond, before, after): return out -def gen_enum_lookup(name, values, prefix=None): +def gen_enum_lookup(name, members, prefix=None): ret = mcgen(''' const QEnumLookup %(c_name)s_lookup = { .array = (const char *const[]) { ''', c_name=c_name(name)) - for value in values: - index = c_enum_const(name, value, prefix) + for m in members: + index = c_enum_const(name, m.name, prefix) ret += mcgen(''' - [%(index)s] = "%(value)s", + [%(index)s] = "%(name)s", ''', - index=index, value=value) + index=index, name=m.name) ret += mcgen(''' }, @@ -2035,9 +2035,9 @@ const QEnumLookup %(c_name)s_lookup = { return ret -def gen_enum(name, values, prefix=None): +def gen_enum(name, members, prefix=None): # append automatically generated _MAX value - enum_values = values + ['_MAX'] + enum_members = members + [QAPISchemaMember('_MAX')] ret = mcgen(''' @@ -2045,11 +2045,11 @@ typedef enum %(c_name)s { ''', c_name=c_name(name)) - for value in enum_values: + for m in enum_members: ret += mcgen(''' %(c_enum)s, ''', - c_enum=c_enum_const(name, value, prefix)) + c_enum=c_enum_const(name, m.name, prefix)) ret += mcgen(''' } %(c_name)s; diff --git a/scripts/qapi/doc.py b/scripts/qapi/doc.py index 987fd3c943..76cb186ff9 100755 --- a/scripts/qapi/doc.py +++ b/scripts/qapi/doc.py @@ -206,7 +206,7 @@ class QAPISchemaGenDocVisitor(qapi.common.QAPISchemaVisitor): def write(self, output_dir): self._gen.write(output_dir, self._prefix + 'qapi-doc.texi') - def visit_enum_type(self, name, info, ifcond, values, prefix): + def visit_enum_type(self, name, info, ifcond, members, prefix): doc = self.cur_doc self._gen.add(TYPE_FMT(type='Enum', name=doc.symbol, diff --git a/scripts/qapi/events.py b/scripts/qapi/events.py index 2ed7902424..f1b88d8786 100644 --- a/scripts/qapi/events.py +++ b/scripts/qapi/events.py @@ -143,8 +143,8 @@ class QAPISchemaGenEventVisitor(QAPISchemaModularCVisitor): QAPISchemaModularCVisitor.__init__( self, prefix, 'qapi-events', ' * Schema-defined QAPI/QMP events', __doc__) - self._enum_name = c_name(prefix + 'QAPIEvent', protect=False) - self._event_names = [] + self._event_enum_name = c_name(prefix + 'QAPIEvent', protect=False) + self._event_enum_members = [] def _begin_module(self, name): types = self._module_basename('qapi-types', name) @@ -170,15 +170,16 @@ class QAPISchemaGenEventVisitor(QAPISchemaModularCVisitor): def visit_end(self): (genc, genh) = self._module[self._main_module] - genh.add(gen_enum(self._enum_name, self._event_names)) - genc.add(gen_enum_lookup(self._enum_name, self._event_names)) + genh.add(gen_enum(self._event_enum_name, self._event_enum_members)) + genc.add(gen_enum_lookup(self._event_enum_name, + self._event_enum_members)) def visit_event(self, name, info, ifcond, arg_type, boxed): with ifcontext(ifcond, self._genh, self._genc): self._genh.add(gen_event_send_decl(name, arg_type, boxed)) self._genc.add(gen_event_send(name, arg_type, boxed, - self._enum_name)) - self._event_names.append(name) + self._event_enum_name)) + self._event_enum_members.append(QAPISchemaMember(name)) def gen_events(schema, output_dir, prefix): diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py index 67d6106f77..417625d54b 100644 --- a/scripts/qapi/introspect.py +++ b/scripts/qapi/introspect.py @@ -174,8 +174,9 @@ const QLitObject %(c_name)s = %(c_string)s; def visit_builtin_type(self, name, info, json_type): self._gen_qlit(name, 'builtin', {'json-type': json_type}, []) - def visit_enum_type(self, name, info, ifcond, values, prefix): - self._gen_qlit(name, 'enum', {'values': values}, ifcond) + def visit_enum_type(self, name, info, ifcond, members, prefix): + self._gen_qlit(name, 'enum', + {'values': [m.name for m in members]}, ifcond) def visit_array_type(self, name, info, ifcond, element_type): element = self._use_type(element_type) diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py index fd7808103c..e8d22c5081 100644 --- a/scripts/qapi/types.py +++ b/scripts/qapi/types.py @@ -212,10 +212,10 @@ class QAPISchemaGenTypeVisitor(QAPISchemaModularCVisitor): self._genh.add(gen_type_cleanup_decl(name)) self._genc.add(gen_type_cleanup(name)) - def visit_enum_type(self, name, info, ifcond, values, prefix): + def visit_enum_type(self, name, info, ifcond, members, prefix): with ifcontext(ifcond, self._genh, self._genc): - self._genh.preamble_add(gen_enum(name, values, prefix)) - self._genc.add(gen_enum_lookup(name, values, prefix)) + self._genh.preamble_add(gen_enum(name, members, prefix)) + self._genc.add(gen_enum_lookup(name, members, prefix)) def visit_array_type(self, name, info, ifcond, element_type): with ifcontext(ifcond, self._genh, self._genc): diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py index 460cf12989..24f85a2e85 100644 --- a/scripts/qapi/visit.py +++ b/scripts/qapi/visit.py @@ -310,7 +310,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor): ''', types=types)) - def visit_enum_type(self, name, info, ifcond, values, prefix): + def visit_enum_type(self, name, info, ifcond, members, prefix): with ifcontext(ifcond, self._genh, self._genc): self._genh.add(gen_visit_decl(name, scalar=True)) self._genc.add(gen_visit_enum(name)) diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py index cea21c773a..27f776693e 100644 --- a/tests/qapi-schema/test-qapi.py +++ b/tests/qapi-schema/test-qapi.py @@ -23,8 +23,8 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor): def visit_include(self, name, info): print('include %s' % name) - def visit_enum_type(self, name, info, ifcond, values, prefix): - print('enum %s %s' % (name, values)) + def visit_enum_type(self, name, info, ifcond, members, prefix): + print('enum %s %s' % (name, [m.name for m in members])) if prefix: print(' prefix %s' % prefix) self._print_if(ifcond) From patchwork Thu Dec 13 18:43:25 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 1013042 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43G2fT6pvwz9s9G for ; Fri, 14 Dec 2018 05:44:49 +1100 (AEDT) Received: from localhost ([::1]:54230 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVyY-0005q8-M9 for incoming@patchwork.ozlabs.org; Thu, 13 Dec 2018 13:44:47 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53269) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVxr-0005l9-Lw for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:05 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXVxp-0002XU-M2 for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:03 -0500 Received: from mx1.redhat.com ([209.132.183.28]:32894) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gXVxn-0001c1-Pp for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:00 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 99988C0050CC for ; Thu, 13 Dec 2018 18:43:48 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-56.ams2.redhat.com [10.36.116.56]) by smtp.corp.redhat.com (Postfix) with ESMTPS id DDFB161B72; Thu, 13 Dec 2018 18:43:46 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 8D9461132C06; Thu, 13 Dec 2018 19:43:40 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2018 19:43:25 +0100 Message-Id: <20181213184340.24037-18-armbru@redhat.com> In-Reply-To: <20181213184340.24037-1-armbru@redhat.com> References: <20181213184340.24037-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Thu, 13 Dec 2018 18:43:48 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 17/32] tests: print enum type members more like object type members X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Commit 93bda4dd461 changed the internal representation of enum type members from str to QAPISchemaMember, but we still print only a string. Has been good enough, as the name is the member's only attribute of interest, but that's about to change. To prepare, print them more like object type members. Signed-off-by: Marc-André Lureau Reviewed-by: Markus Armbruster Message-Id: <20181213123724.4866-4-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster --- tests/qapi-schema/comments.out | 14 ++++++- tests/qapi-schema/doc-bad-section.out | 13 +++++- tests/qapi-schema/doc-good.out | 17 ++++++-- tests/qapi-schema/empty.out | 9 ++++- tests/qapi-schema/event-case.out | 9 ++++- tests/qapi-schema/ident-with-escape.out | 9 ++++- tests/qapi-schema/include-relpath.out | 14 ++++++- tests/qapi-schema/include-repetition.out | 14 ++++++- tests/qapi-schema/include-simple.out | 14 ++++++- tests/qapi-schema/indented-expr.out | 9 ++++- tests/qapi-schema/qapi-schema-test.out | 50 +++++++++++++++++++----- tests/qapi-schema/test-qapi.py | 4 +- 12 files changed, 149 insertions(+), 27 deletions(-) diff --git a/tests/qapi-schema/comments.out b/tests/qapi-schema/comments.out index 8d2f1ce8a2..d1abc4b5a1 100644 --- a/tests/qapi-schema/comments.out +++ b/tests/qapi-schema/comments.out @@ -1,5 +1,15 @@ object q_empty -enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool'] +enum QType prefix QTYPE + member none + member qnull + member qnum + member qstring + member qdict + member qlist + member qbool module comments.json -enum Status ['good', 'bad', 'ugly'] +enum Status + member good + member bad + member ugly diff --git a/tests/qapi-schema/doc-bad-section.out b/tests/qapi-schema/doc-bad-section.out index cd28721568..db8014eed0 100644 --- a/tests/qapi-schema/doc-bad-section.out +++ b/tests/qapi-schema/doc-bad-section.out @@ -1,8 +1,17 @@ object q_empty -enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool'] +enum QType prefix QTYPE + member none + member qnull + member qnum + member qstring + member qdict + member qlist + member qbool module doc-bad-section.json -enum Enum ['one', 'two'] +enum Enum + member one + member two doc symbol=Enum body= == Produces *invalid* texinfo diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out index 35f3f1164c..c2fc5c774a 100644 --- a/tests/qapi-schema/doc-good.out +++ b/tests/qapi-schema/doc-good.out @@ -1,8 +1,17 @@ object q_empty -enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool'] +enum QType prefix QTYPE + member none + member qnull + member qnum + member qstring + member qdict + member qlist + member qbool module doc-good.json -enum Enum ['one', 'two'] +enum Enum + member one + member two if ['defined(IFCOND)'] object Base member base1: Enum optional=False @@ -18,7 +27,9 @@ object q_obj_Variant1-wrapper member data: Variant1 optional=False object q_obj_Variant2-wrapper member data: Variant2 optional=False -enum SugaredUnionKind ['one', 'two'] +enum SugaredUnionKind + member one + member two object SugaredUnion member type: SugaredUnionKind optional=False tag type diff --git a/tests/qapi-schema/empty.out b/tests/qapi-schema/empty.out index 0ec234eec4..5483cb7bc6 100644 --- a/tests/qapi-schema/empty.out +++ b/tests/qapi-schema/empty.out @@ -1,3 +1,10 @@ object q_empty -enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool'] +enum QType prefix QTYPE + member none + member qnull + member qnum + member qstring + member qdict + member qlist + member qbool diff --git a/tests/qapi-schema/event-case.out b/tests/qapi-schema/event-case.out index 88c0964917..f69d4ffe4e 100644 --- a/tests/qapi-schema/event-case.out +++ b/tests/qapi-schema/event-case.out @@ -1,6 +1,13 @@ object q_empty -enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool'] +enum QType prefix QTYPE + member none + member qnull + member qnum + member qstring + member qdict + member qlist + member qbool module event-case.json event oops None boxed=False diff --git a/tests/qapi-schema/ident-with-escape.out b/tests/qapi-schema/ident-with-escape.out index 24c976f473..7f891f7e90 100644 --- a/tests/qapi-schema/ident-with-escape.out +++ b/tests/qapi-schema/ident-with-escape.out @@ -1,6 +1,13 @@ object q_empty -enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool'] +enum QType prefix QTYPE + member none + member qnull + member qnum + member qstring + member qdict + member qlist + member qbool module ident-with-escape.json object q_obj_fooA-arg member bar1: str optional=False diff --git a/tests/qapi-schema/include-relpath.out b/tests/qapi-schema/include-relpath.out index ebbabd7a18..783ccfc855 100644 --- a/tests/qapi-schema/include-relpath.out +++ b/tests/qapi-schema/include-relpath.out @@ -1,9 +1,19 @@ object q_empty -enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool'] +enum QType prefix QTYPE + member none + member qnull + member qnum + member qstring + member qdict + member qlist + member qbool module include-relpath.json include include/relpath.json module include/relpath.json include include-relpath-sub.json module include-relpath-sub.json -enum Status ['good', 'bad', 'ugly'] +enum Status + member good + member bad + member ugly diff --git a/tests/qapi-schema/include-repetition.out b/tests/qapi-schema/include-repetition.out index 7235e055bc..d45977ee56 100644 --- a/tests/qapi-schema/include-repetition.out +++ b/tests/qapi-schema/include-repetition.out @@ -1,10 +1,20 @@ object q_empty -enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool'] +enum QType prefix QTYPE + member none + member qnull + member qnum + member qstring + member qdict + member qlist + member qbool module include-repetition.json include comments.json module comments.json -enum Status ['good', 'bad', 'ugly'] +enum Status + member good + member bad + member ugly module include-repetition.json include include-repetition-sub.json module include-repetition-sub.json diff --git a/tests/qapi-schema/include-simple.out b/tests/qapi-schema/include-simple.out index 006f723eeb..1afe20802a 100644 --- a/tests/qapi-schema/include-simple.out +++ b/tests/qapi-schema/include-simple.out @@ -1,7 +1,17 @@ object q_empty -enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool'] +enum QType prefix QTYPE + member none + member qnull + member qnum + member qstring + member qdict + member qlist + member qbool module include-simple.json include include-simple-sub.json module include-simple-sub.json -enum Status ['good', 'bad', 'ugly'] +enum Status + member good + member bad + member ugly diff --git a/tests/qapi-schema/indented-expr.out b/tests/qapi-schema/indented-expr.out index bd8a48630e..c0cf3243f3 100644 --- a/tests/qapi-schema/indented-expr.out +++ b/tests/qapi-schema/indented-expr.out @@ -1,6 +1,13 @@ object q_empty -enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool'] +enum QType prefix QTYPE + member none + member qnull + member qnum + member qstring + member qdict + member qlist + member qbool module indented-expr.json command eins None -> None gen=True success_response=True boxed=False oob=False preconfig=False diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out index 3ca858dd0e..06e80e5b04 100644 --- a/tests/qapi-schema/qapi-schema-test.out +++ b/tests/qapi-schema/qapi-schema-test.out @@ -1,6 +1,13 @@ object q_empty -enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool'] +enum QType prefix QTYPE + member none + member qnull + member qnum + member qstring + member qdict + member qlist + member qbool module qapi-schema-test.json object TestStruct member integer: int optional=False @@ -11,19 +18,25 @@ object NestedEnumsOne member enum2: EnumOne optional=True member enum3: EnumOne optional=False member enum4: EnumOne optional=True -enum MyEnum [] +enum MyEnum object Empty1 object Empty2 base Empty1 command user_def_cmd0 Empty2 -> Empty2 gen=True success_response=True boxed=False oob=False preconfig=False -enum QEnumTwo ['value1', 'value2'] +enum QEnumTwo prefix QENUM_TWO + member value1 + member value2 object UserDefOne base UserDefZero member string: str optional=False member enum1: EnumOne optional=True -enum EnumOne ['value1', 'value2', 'value3', 'value4'] +enum EnumOne + member value1 + member value2 + member value3 + member value4 object UserDefZero member integer: int optional=False object UserDefTwoDictDict @@ -127,7 +140,21 @@ object q_obj_sizeList-wrapper member data: sizeList optional=False object q_obj_anyList-wrapper member data: anyList optional=False -enum UserDefNativeListUnionKind ['integer', 's8', 's16', 's32', 's64', 'u8', 'u16', 'u32', 'u64', 'number', 'boolean', 'string', 'sizes', 'any'] +enum UserDefNativeListUnionKind + member integer + member s8 + member s16 + member s32 + member s64 + member u8 + member u16 + member u32 + member u64 + member number + member boolean + member string + member sizes + member any object UserDefNativeListUnion member type: UserDefNativeListUnionKind optional=False tag type @@ -204,7 +231,8 @@ event EVENT_E UserDefZero boxed=True event EVENT_F UserDefAlternate boxed=True -enum __org.qemu_x-Enum ['__org.qemu_x-value'] +enum __org.qemu_x-Enum + member __org.qemu_x-value object __org.qemu_x-Base member __org.qemu_x-member1: __org.qemu_x-Enum optional=False object __org.qemu_x-Struct @@ -213,7 +241,8 @@ object __org.qemu_x-Struct member wchar-t: int optional=True object q_obj_str-wrapper member data: str optional=False -enum __org.qemu_x-Union1Kind ['__org.qemu_x-branch'] +enum __org.qemu_x-Union1Kind + member __org.qemu_x-branch object __org.qemu_x-Union1 member type: __org.qemu_x-Union1Kind optional=False tag type @@ -240,11 +269,14 @@ command __org.qemu_x-command q_obj___org.qemu_x-command-arg -> __org.qemu_x-Unio object TestIfStruct member foo: int optional=False if ['defined(TEST_IF_STRUCT)'] -enum TestIfEnum ['foo', 'bar'] +enum TestIfEnum + member foo + member bar if ['defined(TEST_IF_ENUM)'] object q_obj_TestStruct-wrapper member data: TestStruct optional=False -enum TestIfUnionKind ['foo'] +enum TestIfUnionKind + member foo if ['defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)'] object TestIfUnion member type: TestIfUnionKind optional=False diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py index 27f776693e..641a18f06d 100644 --- a/tests/qapi-schema/test-qapi.py +++ b/tests/qapi-schema/test-qapi.py @@ -24,9 +24,11 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor): print('include %s' % name) def visit_enum_type(self, name, info, ifcond, members, prefix): - print('enum %s %s' % (name, [m.name for m in members])) + print('enum %s' % name) if prefix: print(' prefix %s' % prefix) + for m in members: + print(' member %s' % m.name) self._print_if(ifcond) def visit_object_type(self, name, info, ifcond, base, members, variants): From patchwork Thu Dec 13 18:43:26 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 1013077 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43G3BQ360Jz9s9G for ; Fri, 14 Dec 2018 06:09:02 +1100 (AEDT) Received: from localhost ([::1]:54358 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXWLz-0001xG-Sk for incoming@patchwork.ozlabs.org; Thu, 13 Dec 2018 14:08:59 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53394) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVy7-00062J-1j for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:20 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXVxx-00036I-9B for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:14 -0500 Received: from mx1.redhat.com ([209.132.183.28]:33510) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gXVxr-0001eV-NK for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:05 -0500 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7C40A88E51 for ; Thu, 13 Dec 2018 18:43:49 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-56.ams2.redhat.com [10.36.116.56]) by smtp.corp.redhat.com (Postfix) with ESMTPS id E6F6F60C4C; Thu, 13 Dec 2018 18:43:46 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 925011132C10; Thu, 13 Dec 2018 19:43:40 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2018 19:43:26 +0100 Message-Id: <20181213184340.24037-19-armbru@redhat.com> In-Reply-To: <20181213184340.24037-1-armbru@redhat.com> References: <20181213184340.24037-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Thu, 13 Dec 2018 18:43:49 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 18/32] qapi: factor out checking for keys X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Introduce a new helper function to check if the given keys are known, and if mandatory keys are present. The function will be reused in other places in the following code changes. Signed-off-by: Marc-André Lureau Reviewed-by: Markus Armbruster Message-Id: <20181213123724.4866-5-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster --- scripts/qapi/common.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index 1fa2f79990..18f5872808 100644 --- a/scripts/qapi/common.py +++ b/scripts/qapi/common.py @@ -873,6 +873,17 @@ def check_struct(expr, info): allow_metas=['struct']) +def check_known_keys(info, source, keys, required, optional): + for key in keys: + if key not in required and key not in optional: + raise QAPISemError(info, "Unknown key '%s' in %s" % (key, source)) + + for key in required: + if key not in keys: + raise QAPISemError(info, "Key '%s' is missing from %s" + % (key, source)) + + def check_keys(expr_elem, meta, required, optional=[]): expr = expr_elem['expr'] info = expr_elem['info'] @@ -880,10 +891,9 @@ def check_keys(expr_elem, meta, required, optional=[]): if not isinstance(name, str): raise QAPISemError(info, "'%s' key must have a string value" % meta) required = required + [meta] + source = "%s '%s'" % (meta, name) + check_known_keys(info, source, expr.keys(), required, optional) for (key, value) in expr.items(): - if key not in required and key not in optional: - raise QAPISemError(info, "Unknown key '%s' in %s '%s'" - % (key, meta, name)) if key in ['gen', 'success-response'] and value is not False: raise QAPISemError(info, "'%s' of %s '%s' should only use false value" @@ -895,10 +905,6 @@ def check_keys(expr_elem, meta, required, optional=[]): % (key, meta, name)) if key == 'if': check_if(expr, info) - for key in required: - if key not in expr: - raise QAPISemError(info, "Key '%s' is missing from %s '%s'" - % (key, meta, name)) def check_exprs(exprs): From patchwork Thu Dec 13 18:43:27 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 1013074 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43G34T6y5kz9s3Z for ; Fri, 14 Dec 2018 06:03:53 +1100 (AEDT) Received: from localhost ([::1]:54332 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXWH1-0005y6-G1 for incoming@patchwork.ozlabs.org; Thu, 13 Dec 2018 14:03:51 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53270) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVxr-0005lA-MN for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:05 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXVxo-0002SN-FG for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:03 -0500 Received: from mx1.redhat.com ([209.132.183.28]:59748) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gXVxm-0001dD-1y for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:59 -0500 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C7A7B3001FCD for ; Thu, 13 Dec 2018 18:43:48 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-56.ams2.redhat.com [10.36.116.56]) by smtp.corp.redhat.com (Postfix) with ESMTPS id E63D9600C0; Thu, 13 Dec 2018 18:43:46 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 966941132C11; Thu, 13 Dec 2018 19:43:40 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2018 19:43:27 +0100 Message-Id: <20181213184340.24037-20-armbru@redhat.com> In-Reply-To: <20181213184340.24037-1-armbru@redhat.com> References: <20181213184340.24037-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.45]); Thu, 13 Dec 2018 18:43:48 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 19/32] qapi: improve reporting of unknown or missing keys X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Report the set of missing or unknown keys. And give a hint about the accepted keys. The error message for multiple meta type members (visible in tests/qapi-schema/double-type.err) is not improved. Signed-off-by: Marc-André Lureau Reviewed-by: Markus Armbruster Message-Id: <20181213123724.4866-6-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster --- scripts/qapi/common.py | 21 ++++++++++++++------- tests/qapi-schema/alternate-base.err | 1 + tests/qapi-schema/double-type.err | 1 + tests/qapi-schema/unknown-expr-key.err | 3 ++- tests/qapi-schema/unknown-expr-key.json | 2 +- 5 files changed, 19 insertions(+), 9 deletions(-) diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index 18f5872808..f205805751 100644 --- a/scripts/qapi/common.py +++ b/scripts/qapi/common.py @@ -874,14 +874,21 @@ def check_struct(expr, info): def check_known_keys(info, source, keys, required, optional): - for key in keys: - if key not in required and key not in optional: - raise QAPISemError(info, "Unknown key '%s' in %s" % (key, source)) - for key in required: - if key not in keys: - raise QAPISemError(info, "Key '%s' is missing from %s" - % (key, source)) + def pprint(elems): + return ', '.join("'" + e + "'" for e in sorted(elems)) + + missing = set(required) - set(keys) + if missing: + raise QAPISemError(info, "Key%s %s %s missing from %s" + % ('s' if len(missing) > 1 else '', pprint(missing), + 'are' if len(missing) > 1 else 'is', source)) + allowed = set(required + optional) + unknown = set(keys) - allowed + if unknown: + raise QAPISemError(info, "Unknown key%s %s in %s\nValid keys are %s." + % ('s' if len(unknown) > 1 else '', pprint(unknown), + source, pprint(allowed))) def check_keys(expr_elem, meta, required, optional=[]): diff --git a/tests/qapi-schema/alternate-base.err b/tests/qapi-schema/alternate-base.err index 30d8a34373..ebe05bc898 100644 --- a/tests/qapi-schema/alternate-base.err +++ b/tests/qapi-schema/alternate-base.err @@ -1 +1,2 @@ tests/qapi-schema/alternate-base.json:4: Unknown key 'base' in alternate 'Alt' +Valid keys are 'alternate', 'data', 'if'. diff --git a/tests/qapi-schema/double-type.err b/tests/qapi-schema/double-type.err index f9613c6d6b..799193dba1 100644 --- a/tests/qapi-schema/double-type.err +++ b/tests/qapi-schema/double-type.err @@ -1 +1,2 @@ tests/qapi-schema/double-type.json:2: Unknown key 'command' in struct 'bar' +Valid keys are 'base', 'data', 'if', 'struct'. diff --git a/tests/qapi-schema/unknown-expr-key.err b/tests/qapi-schema/unknown-expr-key.err index 12f5ed5b43..6ff8bb99c5 100644 --- a/tests/qapi-schema/unknown-expr-key.err +++ b/tests/qapi-schema/unknown-expr-key.err @@ -1 +1,2 @@ -tests/qapi-schema/unknown-expr-key.json:2: Unknown key 'bogus' in struct 'bar' +tests/qapi-schema/unknown-expr-key.json:2: Unknown keys 'bogus', 'phony' in struct 'bar' +Valid keys are 'base', 'data', 'if', 'struct'. diff --git a/tests/qapi-schema/unknown-expr-key.json b/tests/qapi-schema/unknown-expr-key.json index 3b2be00cc4..13292d75ed 100644 --- a/tests/qapi-schema/unknown-expr-key.json +++ b/tests/qapi-schema/unknown-expr-key.json @@ -1,2 +1,2 @@ # we reject an expression with unknown top-level keys -{ 'struct': 'bar', 'data': { 'string': 'str'}, 'bogus': { } } +{ 'struct': 'bar', 'data': { 'string': 'str'}, 'bogus': { }, 'phony': { } } From patchwork Thu Dec 13 18:43:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 1013061 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43G30G6Q8Zz9s9G for ; Fri, 14 Dec 2018 06:00:14 +1100 (AEDT) Received: from localhost ([::1]:54307 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXWDU-0002ib-Es for incoming@patchwork.ozlabs.org; Thu, 13 Dec 2018 14:00:12 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53395) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVy7-00062K-1n for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:20 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXVxx-00036K-96 for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:14 -0500 Received: from mx1.redhat.com ([209.132.183.28]:58582) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gXVxr-0001eH-OU for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:05 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6A1D33082139 for ; Thu, 13 Dec 2018 18:43:49 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-56.ams2.redhat.com [10.36.116.56]) by smtp.corp.redhat.com (Postfix) with ESMTPS id E98B6648D3; Thu, 13 Dec 2018 18:43:46 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 9A7651132C12; Thu, 13 Dec 2018 19:43:40 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2018 19:43:28 +0100 Message-Id: <20181213184340.24037-21-armbru@redhat.com> In-Reply-To: <20181213184340.24037-1-armbru@redhat.com> References: <20181213184340.24037-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.42]); Thu, 13 Dec 2018 18:43:49 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 20/32] qapi: add a dictionary form with 'name' key for enum members X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Desugar the enum NAME form to { 'name': NAME }. This will allow to add new enum members, such as 'if' in the following patch. Signed-off-by: Marc-André Lureau Message-Id: <20181213123724.4866-7-marcandre.lureau@redhat.com> Message-Id: <20181213123724.4866-8-marcandre.lureau@redhat.com> Message-Id: <20181213123724.4866-9-marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster [Harmless accidental move backed out, long line wrapped, patches squashed] Signed-off-by: Markus Armbruster --- scripts/qapi/common.py | 36 +++++++++++++------ tests/Makefile.include | 3 +- tests/qapi-schema/enum-bad-member.err | 1 + ...-dict-member.exit => enum-bad-member.exit} | 0 tests/qapi-schema/enum-bad-member.json | 2 ++ ...um-dict-member.out => enum-bad-member.out} | 0 .../qapi-schema/enum-dict-member-unknown.err | 2 ++ .../qapi-schema/enum-dict-member-unknown.exit | 1 + .../qapi-schema/enum-dict-member-unknown.json | 2 ++ .../qapi-schema/enum-dict-member-unknown.out | 0 tests/qapi-schema/enum-dict-member.err | 1 - tests/qapi-schema/enum-dict-member.json | 2 -- 12 files changed, 36 insertions(+), 14 deletions(-) create mode 100644 tests/qapi-schema/enum-bad-member.err rename tests/qapi-schema/{enum-dict-member.exit => enum-bad-member.exit} (100%) create mode 100644 tests/qapi-schema/enum-bad-member.json rename tests/qapi-schema/{enum-dict-member.out => enum-bad-member.out} (100%) create mode 100644 tests/qapi-schema/enum-dict-member-unknown.err create mode 100644 tests/qapi-schema/enum-dict-member-unknown.exit create mode 100644 tests/qapi-schema/enum-dict-member-unknown.json create mode 100644 tests/qapi-schema/enum-dict-member-unknown.out delete mode 100644 tests/qapi-schema/enum-dict-member.err delete mode 100644 tests/qapi-schema/enum-dict-member.json diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index f205805751..b1cf33af21 100644 --- a/scripts/qapi/common.py +++ b/scripts/qapi/common.py @@ -740,6 +740,10 @@ def check_event(expr, info): allow_metas=meta) +def enum_get_names(expr): + return [e['name'] for e in expr['data']] + + def check_union(expr, info): name = expr['union'] base = expr.get('base') @@ -799,7 +803,7 @@ def check_union(expr, info): # If the discriminator names an enum type, then all members # of 'data' must also be members of the enum type. if enum_define: - if key not in enum_define['data']: + if key not in enum_get_names(enum_define): raise QAPISemError(info, "Discriminator value '%s' is not found in " "enum '%s'" @@ -831,7 +835,7 @@ def check_alternate(expr, info): if qtype == 'QTYPE_QSTRING': enum_expr = enum_types.get(value) if enum_expr: - for v in enum_expr['data']: + for v in enum_get_names(enum_expr): if v in ['on', 'off']: conflicting.add('QTYPE_QBOOL') if re.match(r'[-+0-9.]', v): # lazy, could be tightened @@ -847,9 +851,15 @@ def check_alternate(expr, info): types_seen[qt] = key +def normalize_enum(expr): + if isinstance(expr['data'], list): + expr['data'] = [m if isinstance(m, dict) else {'name': m} + for m in expr['data']] + + def check_enum(expr, info): name = expr['enum'] - members = expr.get('data') + members = expr['data'] prefix = expr.get('prefix') if not isinstance(members, list): @@ -858,8 +868,11 @@ def check_enum(expr, info): if prefix is not None and not isinstance(prefix, str): raise QAPISemError(info, "Enum '%s' requires a string for 'prefix'" % name) + for member in members: - check_name(info, "Member of enum '%s'" % name, member, + source = "dictionary member of enum '%s'" % name + check_known_keys(info, source, member, ['name'], []) + check_name(info, "Member of enum '%s'" % name, member['name'], enum_member=True) @@ -937,6 +950,7 @@ def check_exprs(exprs): if 'enum' in expr: meta = 'enum' check_keys(expr_elem, 'enum', ['data'], ['if', 'prefix']) + normalize_enum(expr) enum_types[expr[meta]] = expr elif 'union' in expr: meta = 'union' @@ -1633,14 +1647,16 @@ class QAPISchema(object): self.the_empty_object_type = QAPISchemaObjectType( 'q_empty', None, None, None, None, [], None) self._def_entity(self.the_empty_object_type) - qtype_values = self._make_enum_members(['none', 'qnull', 'qnum', - 'qstring', 'qdict', 'qlist', - 'qbool']) + + qtypes = ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', + 'qbool'] + qtype_values = self._make_enum_members([{'name': n} for n in qtypes]) + self._def_entity(QAPISchemaEnumType('QType', None, None, None, qtype_values, 'QTYPE')) def _make_enum_members(self, values): - return [QAPISchemaMember(v) for v in values] + return [QAPISchemaMember(v['name']) for v in values] def _make_implicit_enum_type(self, name, info, ifcond, values): # See also QAPISchemaObjectTypeMember._pretty_owner() @@ -1740,8 +1756,8 @@ class QAPISchema(object): else: variants = [self._make_simple_variant(key, value, info) for (key, value) in data.items()] - typ = self._make_implicit_enum_type(name, info, ifcond, - [v.name for v in variants]) + enum = [{'name': v.name} for v in variants] + typ = self._make_implicit_enum_type(name, info, ifcond, enum) tag_member = QAPISchemaObjectTypeMember('type', typ, False) members = [tag_member] self._def_entity( diff --git a/tests/Makefile.include b/tests/Makefile.include index fb0b449c02..2e894c1037 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -379,10 +379,11 @@ qapi-schema += double-data.json qapi-schema += double-type.json qapi-schema += duplicate-key.json qapi-schema += empty.json +qapi-schema += enum-bad-member.json qapi-schema += enum-bad-name.json qapi-schema += enum-bad-prefix.json qapi-schema += enum-clash-member.json -qapi-schema += enum-dict-member.json +qapi-schema += enum-dict-member-unknown.json qapi-schema += enum-int-member.json qapi-schema += enum-member-case.json qapi-schema += enum-missing-data.json diff --git a/tests/qapi-schema/enum-bad-member.err b/tests/qapi-schema/enum-bad-member.err new file mode 100644 index 0000000000..211db9e6fc --- /dev/null +++ b/tests/qapi-schema/enum-bad-member.err @@ -0,0 +1 @@ +tests/qapi-schema/enum-bad-member.json:2: Member of enum 'MyEnum' requires a string name diff --git a/tests/qapi-schema/enum-dict-member.exit b/tests/qapi-schema/enum-bad-member.exit similarity index 100% rename from tests/qapi-schema/enum-dict-member.exit rename to tests/qapi-schema/enum-bad-member.exit diff --git a/tests/qapi-schema/enum-bad-member.json b/tests/qapi-schema/enum-bad-member.json new file mode 100644 index 0000000000..98da6828b4 --- /dev/null +++ b/tests/qapi-schema/enum-bad-member.json @@ -0,0 +1,2 @@ +# we reject any enum member that is not a string +{ 'enum': 'MyEnum', 'data': [ [ ] ] } diff --git a/tests/qapi-schema/enum-dict-member.out b/tests/qapi-schema/enum-bad-member.out similarity index 100% rename from tests/qapi-schema/enum-dict-member.out rename to tests/qapi-schema/enum-bad-member.out diff --git a/tests/qapi-schema/enum-dict-member-unknown.err b/tests/qapi-schema/enum-dict-member-unknown.err new file mode 100644 index 0000000000..76bd0471db --- /dev/null +++ b/tests/qapi-schema/enum-dict-member-unknown.err @@ -0,0 +1,2 @@ +tests/qapi-schema/enum-dict-member-unknown.json:2: Unknown key 'bad-key' in dictionary member of enum 'MyEnum' +Valid keys are 'name'. diff --git a/tests/qapi-schema/enum-dict-member-unknown.exit b/tests/qapi-schema/enum-dict-member-unknown.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/enum-dict-member-unknown.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/enum-dict-member-unknown.json b/tests/qapi-schema/enum-dict-member-unknown.json new file mode 100644 index 0000000000..6664c59201 --- /dev/null +++ b/tests/qapi-schema/enum-dict-member-unknown.json @@ -0,0 +1,2 @@ +# we reject any enum member that is not a string or a dict with 'name' +{ 'enum': 'MyEnum', 'data': [ { 'name': 'foo', 'bad-key': 'str' } ] } diff --git a/tests/qapi-schema/enum-dict-member-unknown.out b/tests/qapi-schema/enum-dict-member-unknown.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/enum-dict-member.err b/tests/qapi-schema/enum-dict-member.err deleted file mode 100644 index 8ca146ea59..0000000000 --- a/tests/qapi-schema/enum-dict-member.err +++ /dev/null @@ -1 +0,0 @@ -tests/qapi-schema/enum-dict-member.json:2: Member of enum 'MyEnum' requires a string name diff --git a/tests/qapi-schema/enum-dict-member.json b/tests/qapi-schema/enum-dict-member.json deleted file mode 100644 index 79672e0f09..0000000000 --- a/tests/qapi-schema/enum-dict-member.json +++ /dev/null @@ -1,2 +0,0 @@ -# we reject any enum member that is not a string -{ 'enum': 'MyEnum', 'data': [ { 'value': 'str' } ] } From patchwork Thu Dec 13 18:43:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 1013066 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43G33r14CLz9s3Z for ; Fri, 14 Dec 2018 06:03:20 +1100 (AEDT) Received: from localhost ([::1]:54326 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXWGT-0004wF-6W for incoming@patchwork.ozlabs.org; Thu, 13 Dec 2018 14:03:17 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53322) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVxv-0005pn-IS for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXVxr-0002i0-L5 for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:05 -0500 Received: from mx1.redhat.com ([209.132.183.28]:41472) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gXVxo-0001eh-Gh for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:01 -0500 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9775180496 for ; Thu, 13 Dec 2018 18:43:49 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-56.ams2.redhat.com [10.36.116.56]) by smtp.corp.redhat.com (Postfix) with ESMTPS id ED6E560C69; Thu, 13 Dec 2018 18:43:46 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 9F38E1132C13; Thu, 13 Dec 2018 19:43:40 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2018 19:43:29 +0100 Message-Id: <20181213184340.24037-22-armbru@redhat.com> In-Reply-To: <20181213184340.24037-1-armbru@redhat.com> References: <20181213184340.24037-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Thu, 13 Dec 2018 18:43:49 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 21/32] qapi: add 'if' to enum members X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau QAPISchemaMember gains .ifcond for enum members: inherited classes, such as QAPISchemaObjectTypeMember, will thus have an ifcond member after this (those different types will also use the .ifcond to store the condition and generate conditional code in the following patches). The generated code remains unconditional for now. Later patches generate the conditionals. Signed-off-by: Marc-André Lureau Reviewed-by: Markus Armbruster Message-Id: <20181213123724.4866-10-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster --- docs/devel/qapi-code-gen.txt | 9 +++++++++ scripts/qapi/common.py | 8 +++++--- tests/Makefile.include | 1 + tests/qapi-schema/enum-dict-member-unknown.err | 2 +- tests/qapi-schema/enum-if-invalid.err | 1 + tests/qapi-schema/enum-if-invalid.exit | 1 + tests/qapi-schema/enum-if-invalid.json | 3 +++ tests/qapi-schema/enum-if-invalid.out | 0 tests/qapi-schema/qapi-schema-test.json | 5 +++-- tests/qapi-schema/qapi-schema-test.out | 2 ++ tests/qapi-schema/test-qapi.py | 1 + 11 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 tests/qapi-schema/enum-if-invalid.err create mode 100644 tests/qapi-schema/enum-if-invalid.exit create mode 100644 tests/qapi-schema/enum-if-invalid.json create mode 100644 tests/qapi-schema/enum-if-invalid.out diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt index 2c8b392b20..7ba9066eac 100644 --- a/docs/devel/qapi-code-gen.txt +++ b/docs/devel/qapi-code-gen.txt @@ -752,6 +752,15 @@ gets its generated code guarded like this: #endif /* defined(HAVE_BAR) */ #endif /* defined(CONFIG_FOO) */ +An enum value can be replaced by a dictionary with a 'name' and a 'if' +key. + +Example: a conditional 'bar' enum member. + +{ 'enum': 'IfEnum', 'data': + [ 'foo', + { 'name' : 'bar', 'if': 'defined(IFCOND)' } ] } + Please note that you are responsible to ensure that the C code will compile with an arbitrary combination of conditions, since the generators are unable to check it at this point. diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index b1cf33af21..a609ffcfee 100644 --- a/scripts/qapi/common.py +++ b/scripts/qapi/common.py @@ -871,7 +871,8 @@ def check_enum(expr, info): for member in members: source = "dictionary member of enum '%s'" % name - check_known_keys(info, source, member, ['name'], []) + check_known_keys(info, source, member, ['name'], ['if']) + check_if(member, info) check_name(info, "Member of enum '%s'" % name, member['name'], enum_member=True) @@ -1345,9 +1346,10 @@ class QAPISchemaObjectType(QAPISchemaType): class QAPISchemaMember(object): role = 'member' - def __init__(self, name): + def __init__(self, name, ifcond=None): assert isinstance(name, str) self.name = name + self.ifcond = listify_cond(ifcond) self.owner = None def set_owner(self, name): @@ -1656,7 +1658,7 @@ class QAPISchema(object): qtype_values, 'QTYPE')) def _make_enum_members(self, values): - return [QAPISchemaMember(v['name']) for v in values] + return [QAPISchemaMember(v['name'], v.get('if')) for v in values] def _make_implicit_enum_type(self, name, info, ifcond, values): # See also QAPISchemaObjectTypeMember._pretty_owner() diff --git a/tests/Makefile.include b/tests/Makefile.include index 2e894c1037..3c9eea27fd 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -384,6 +384,7 @@ qapi-schema += enum-bad-name.json qapi-schema += enum-bad-prefix.json qapi-schema += enum-clash-member.json qapi-schema += enum-dict-member-unknown.json +qapi-schema += enum-if-invalid.json qapi-schema += enum-int-member.json qapi-schema += enum-member-case.json qapi-schema += enum-missing-data.json diff --git a/tests/qapi-schema/enum-dict-member-unknown.err b/tests/qapi-schema/enum-dict-member-unknown.err index 76bd0471db..2aae618be0 100644 --- a/tests/qapi-schema/enum-dict-member-unknown.err +++ b/tests/qapi-schema/enum-dict-member-unknown.err @@ -1,2 +1,2 @@ tests/qapi-schema/enum-dict-member-unknown.json:2: Unknown key 'bad-key' in dictionary member of enum 'MyEnum' -Valid keys are 'name'. +Valid keys are 'if', 'name'. diff --git a/tests/qapi-schema/enum-if-invalid.err b/tests/qapi-schema/enum-if-invalid.err new file mode 100644 index 0000000000..54c3cf887b --- /dev/null +++ b/tests/qapi-schema/enum-if-invalid.err @@ -0,0 +1 @@ +tests/qapi-schema/enum-if-invalid.json:2: 'if' condition must be a string or a list of strings diff --git a/tests/qapi-schema/enum-if-invalid.exit b/tests/qapi-schema/enum-if-invalid.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/enum-if-invalid.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/enum-if-invalid.json b/tests/qapi-schema/enum-if-invalid.json new file mode 100644 index 0000000000..60bd0ef1d7 --- /dev/null +++ b/tests/qapi-schema/enum-if-invalid.json @@ -0,0 +1,3 @@ +# check invalid 'if' type +{ 'enum': 'TestIfEnum', 'data': + [ 'foo', { 'name' : 'bar', 'if': { 'val': 'foo' } } ] } diff --git a/tests/qapi-schema/enum-if-invalid.out b/tests/qapi-schema/enum-if-invalid.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json index 15388ae9a4..8bfaf5aedd 100644 --- a/tests/qapi-schema/qapi-schema-test.json +++ b/tests/qapi-schema/qapi-schema-test.json @@ -204,7 +204,8 @@ { 'struct': 'TestIfStruct', 'data': { 'foo': 'int' }, 'if': 'defined(TEST_IF_STRUCT)' } -{ 'enum': 'TestIfEnum', 'data': [ 'foo', 'bar' ], +{ 'enum': 'TestIfEnum', 'data': + [ 'foo', { 'name' : 'bar', 'if': 'defined(TEST_IF_ENUM_BAR)' } ], 'if': 'defined(TEST_IF_ENUM)' } { 'union': 'TestIfUnion', 'data': { 'foo': 'TestStruct' }, @@ -219,7 +220,7 @@ { 'command': 'TestIfAlternateCmd', 'data': { 'alt_cmd_arg': 'TestIfAlternate' }, 'if': 'defined(TEST_IF_ALT)' } -{ 'command': 'TestIfCmd', 'data': { 'foo': 'TestIfStruct' }, +{ 'command': 'TestIfCmd', 'data': { 'foo': 'TestIfStruct', 'bar': 'TestIfEnum' }, 'returns': 'UserDefThree', 'if': ['defined(TEST_IF_CMD)', 'defined(TEST_IF_STRUCT)'] } diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out index 06e80e5b04..d90d987651 100644 --- a/tests/qapi-schema/qapi-schema-test.out +++ b/tests/qapi-schema/qapi-schema-test.out @@ -272,6 +272,7 @@ object TestIfStruct enum TestIfEnum member foo member bar + if ['defined(TEST_IF_ENUM_BAR)'] if ['defined(TEST_IF_ENUM)'] object q_obj_TestStruct-wrapper member data: TestStruct optional=False @@ -302,6 +303,7 @@ command TestIfAlternateCmd q_obj_TestIfAlternateCmd-arg -> None if ['defined(TEST_IF_ALT)'] object q_obj_TestIfCmd-arg member foo: TestIfStruct optional=False + member bar: TestIfEnum optional=False if ['defined(TEST_IF_CMD)', 'defined(TEST_IF_STRUCT)'] command TestIfCmd q_obj_TestIfCmd-arg -> UserDefThree gen=True success_response=True boxed=False oob=False preconfig=False diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py index 641a18f06d..aadf252d9d 100644 --- a/tests/qapi-schema/test-qapi.py +++ b/tests/qapi-schema/test-qapi.py @@ -29,6 +29,7 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor): print(' prefix %s' % prefix) for m in members: print(' member %s' % m.name) + self._print_if(m.ifcond, indent=8) self._print_if(ifcond) def visit_object_type(self, name, info, ifcond, base, members, variants): From patchwork Thu Dec 13 18:43:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 1013072 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43G34715xcz9s3Z for ; Fri, 14 Dec 2018 06:03:35 +1100 (AEDT) Received: from localhost ([::1]:54329 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXWGi-00059Q-7H for incoming@patchwork.ozlabs.org; Thu, 13 Dec 2018 14:03:32 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53465) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVyG-0006Ba-I6 for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:29 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXVyF-0004Oc-O5 for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:28 -0500 Received: from mx1.redhat.com ([209.132.183.28]:47442) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gXVyF-0001cd-EE for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:27 -0500 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A5FCD9B427 for ; Thu, 13 Dec 2018 18:43:48 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-56.ams2.redhat.com [10.36.116.56]) by smtp.corp.redhat.com (Postfix) with ESMTPS id EDCB96012B; Thu, 13 Dec 2018 18:43:46 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id A32CE1132C14; Thu, 13 Dec 2018 19:43:40 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2018 19:43:30 +0100 Message-Id: <20181213184340.24037-23-armbru@redhat.com> In-Reply-To: <20181213184340.24037-1-armbru@redhat.com> References: <20181213184340.24037-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Thu, 13 Dec 2018 18:43:48 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 22/32] qapi-events: add 'if' condition to implicit event enum X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Add condition to QAPIEvent enum members based on the event 'if'. The generated code remains unconditional for now. Later patches generate the conditionals (also there is no additional coverage of this change in qapi-schema-test.out since the event_names enum is an implicit type created by qapi/events.py). Signed-off-by: Marc-André Lureau Reviewed-by: Markus Armbruster Message-Id: <20181213123724.4866-11-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster --- scripts/qapi/events.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/qapi/events.py b/scripts/qapi/events.py index f1b88d8786..37ee5de682 100644 --- a/scripts/qapi/events.py +++ b/scripts/qapi/events.py @@ -179,7 +179,7 @@ class QAPISchemaGenEventVisitor(QAPISchemaModularCVisitor): self._genh.add(gen_event_send_decl(name, arg_type, boxed)) self._genc.add(gen_event_send(name, arg_type, boxed, self._event_enum_name)) - self._event_enum_members.append(QAPISchemaMember(name)) + self._event_enum_members.append(QAPISchemaMember(name, ifcond)) def gen_events(schema, output_dir, prefix): From patchwork Thu Dec 13 18:43:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 1013073 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43G34B6fCVz9s3Z for ; Fri, 14 Dec 2018 06:03:38 +1100 (AEDT) Received: from localhost ([::1]:54330 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXWGm-0005GV-Cf for incoming@patchwork.ozlabs.org; Thu, 13 Dec 2018 14:03:36 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53442) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVyF-0006AM-AH for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:30 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXVy9-0003zH-G2 for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:25 -0500 Received: from mx1.redhat.com ([209.132.183.28]:47446) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gXVy6-0001dh-80 for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:19 -0500 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 258A62BE87 for ; Thu, 13 Dec 2018 18:43:49 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-56.ams2.redhat.com [10.36.116.56]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 2A26F6012E; Thu, 13 Dec 2018 18:43:47 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id A77A31132C15; Thu, 13 Dec 2018 19:43:40 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2018 19:43:31 +0100 Message-Id: <20181213184340.24037-24-armbru@redhat.com> In-Reply-To: <20181213184340.24037-1-armbru@redhat.com> References: <20181213184340.24037-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Thu, 13 Dec 2018 18:43:49 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 23/32] qapi: add a dictionary form for TYPE X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Wherever a struct/union/alternate/command/event member with NAME: TYPE form is accepted, desugar it to a NAME: { 'type': TYPE } form. This will allow to add new member details, such as 'if' in the following patch to introduce conditionals, or 'default' for default values etc. Signed-off-by: Marc-André Lureau Message-Id: <20181213123724.4866-13-marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster --- scripts/qapi/common.py | 70 ++++++++++++------- tests/Makefile.include | 6 ++ tests/qapi-schema/alternate-invalid-dict.err | 1 + tests/qapi-schema/alternate-invalid-dict.exit | 1 + tests/qapi-schema/alternate-invalid-dict.json | 4 ++ tests/qapi-schema/alternate-invalid-dict.out | 0 .../qapi-schema/event-member-invalid-dict.err | 1 + .../event-member-invalid-dict.exit | 1 + .../event-member-invalid-dict.json | 2 + .../qapi-schema/event-member-invalid-dict.out | 0 tests/qapi-schema/event-nest-struct.json | 2 +- .../flat-union-inline-invalid-dict.err | 1 + .../flat-union-inline-invalid-dict.exit | 1 + .../flat-union-inline-invalid-dict.json | 11 +++ .../flat-union-inline-invalid-dict.out | 0 tests/qapi-schema/flat-union-inline.json | 2 +- .../nested-struct-data-invalid-dict.err | 1 + .../nested-struct-data-invalid-dict.exit | 1 + .../nested-struct-data-invalid-dict.json | 3 + .../nested-struct-data-invalid-dict.out | 0 tests/qapi-schema/nested-struct-data.json | 2 +- tests/qapi-schema/qapi-schema-test.json | 10 +-- .../struct-member-invalid-dict.err | 1 + .../struct-member-invalid-dict.exit | 1 + .../struct-member-invalid-dict.json | 3 + .../struct-member-invalid-dict.out | 0 .../qapi-schema/union-branch-invalid-dict.err | 1 + .../union-branch-invalid-dict.exit | 1 + .../union-branch-invalid-dict.json | 4 ++ .../qapi-schema/union-branch-invalid-dict.out | 0 30 files changed, 99 insertions(+), 32 deletions(-) create mode 100644 tests/qapi-schema/alternate-invalid-dict.err create mode 100644 tests/qapi-schema/alternate-invalid-dict.exit create mode 100644 tests/qapi-schema/alternate-invalid-dict.json create mode 100644 tests/qapi-schema/alternate-invalid-dict.out create mode 100644 tests/qapi-schema/event-member-invalid-dict.err create mode 100644 tests/qapi-schema/event-member-invalid-dict.exit create mode 100644 tests/qapi-schema/event-member-invalid-dict.json create mode 100644 tests/qapi-schema/event-member-invalid-dict.out create mode 100644 tests/qapi-schema/flat-union-inline-invalid-dict.err create mode 100644 tests/qapi-schema/flat-union-inline-invalid-dict.exit create mode 100644 tests/qapi-schema/flat-union-inline-invalid-dict.json create mode 100644 tests/qapi-schema/flat-union-inline-invalid-dict.out create mode 100644 tests/qapi-schema/nested-struct-data-invalid-dict.err create mode 100644 tests/qapi-schema/nested-struct-data-invalid-dict.exit create mode 100644 tests/qapi-schema/nested-struct-data-invalid-dict.json create mode 100644 tests/qapi-schema/nested-struct-data-invalid-dict.out create mode 100644 tests/qapi-schema/struct-member-invalid-dict.err create mode 100644 tests/qapi-schema/struct-member-invalid-dict.exit create mode 100644 tests/qapi-schema/struct-member-invalid-dict.json create mode 100644 tests/qapi-schema/struct-member-invalid-dict.out create mode 100644 tests/qapi-schema/union-branch-invalid-dict.err create mode 100644 tests/qapi-schema/union-branch-invalid-dict.exit create mode 100644 tests/qapi-schema/union-branch-invalid-dict.json create mode 100644 tests/qapi-schema/union-branch-invalid-dict.out diff --git a/tests/qapi-schema/union-branch-invalid-dict.out b/tests/qapi-schema/union-branch-invalid-dict.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index a609ffcfee..cdfe2bf2a5 100644 --- a/scripts/qapi/common.py +++ b/scripts/qapi/common.py @@ -588,11 +588,11 @@ def discriminator_find_enum_define(expr): if not base_members: return None - discriminator_type = base_members.get(discriminator) - if not discriminator_type: + discriminator_value = base_members.get(discriminator) + if not discriminator_value: return None - return enum_types.get(discriminator_type) + return enum_types.get(discriminator_value['type']) # Names must be letters, numbers, -, and _. They must start with letter, @@ -704,8 +704,10 @@ def check_type(info, source, value, allow_array=False, % (source, key)) # Todo: allow dictionaries to represent default values of # an optional argument. - check_type(info, "Member '%s' of %s" % (key, source), arg, - allow_array=True, + check_known_keys(info, "member '%s' of %s" % (key, source), + arg, ['type'], []) + check_type(info, "Member '%s' of %s" % (key, source), + arg['type'], allow_array=True, allow_metas=['built-in', 'union', 'alternate', 'struct', 'enum']) @@ -776,13 +778,13 @@ def check_union(expr, info): # member of the base struct. check_name(info, "Discriminator of flat union '%s'" % name, discriminator) - discriminator_type = base_members.get(discriminator) - if not discriminator_type: + discriminator_value = base_members.get(discriminator) + if not discriminator_value: raise QAPISemError(info, "Discriminator '%s' is not a member of base " "struct '%s'" % (discriminator, base)) - enum_define = enum_types.get(discriminator_type) + enum_define = enum_types.get(discriminator_value['type']) allow_metas = ['struct'] # Do not allow string discriminator if not enum_define: @@ -796,9 +798,12 @@ def check_union(expr, info): for (key, value) in members.items(): check_name(info, "Member of union '%s'" % name, key) + check_known_keys(info, "member '%s' of union '%s'" % (key, name), + value, ['type'], []) # Each value must name a known type check_type(info, "Member '%s' of union '%s'" % (key, name), - value, allow_array=not base, allow_metas=allow_metas) + value['type'], + allow_array=not base, allow_metas=allow_metas) # If the discriminator names an enum type, then all members # of 'data' must also be members of the enum type. @@ -822,18 +827,21 @@ def check_alternate(expr, info): "in 'data'" % name) for (key, value) in members.items(): check_name(info, "Member of alternate '%s'" % name, key) + check_known_keys(info, + "member '%s' of alternate '%s'" % (key, name), + value, ['type'], []) + typ = value['type'] # Ensure alternates have no type conflicts. - check_type(info, "Member '%s' of alternate '%s'" % (key, name), - value, + check_type(info, "Member '%s' of alternate '%s'" % (key, name), typ, allow_metas=['built-in', 'union', 'struct', 'enum']) - qtype = find_alternate_member_qtype(value) + qtype = find_alternate_member_qtype(typ) if not qtype: raise QAPISemError(info, "Alternate '%s' member '%s' cannot use " - "type '%s'" % (name, key, value)) + "type '%s'" % (name, key, typ)) conflicting = set([qtype]) if qtype == 'QTYPE_QSTRING': - enum_expr = enum_types.get(value) + enum_expr = enum_types.get(typ) if enum_expr: for v in enum_get_names(enum_expr): if v in ['on', 'off']: @@ -851,12 +859,6 @@ def check_alternate(expr, info): types_seen[qt] = key -def normalize_enum(expr): - if isinstance(expr['data'], list): - expr['data'] = [m if isinstance(m, dict) else {'name': m} - for m in expr['data']] - - def check_enum(expr, info): name = expr['enum'] members = expr['data'] @@ -928,6 +930,20 @@ def check_keys(expr_elem, meta, required, optional=[]): check_if(expr, info) +def normalize_enum(expr): + if isinstance(expr['data'], list): + expr['data'] = [m if isinstance(m, dict) else {'name': m} + for m in expr['data']] + + +def normalize_members(members): + if isinstance(members, OrderedDict): + for key, arg in members.items(): + if isinstance(arg, dict): + continue + members[key] = {'type': arg} + + def check_exprs(exprs): global all_names @@ -957,22 +973,28 @@ def check_exprs(exprs): meta = 'union' check_keys(expr_elem, 'union', ['data'], ['base', 'discriminator', 'if']) + normalize_members(expr.get('base')) + normalize_members(expr['data']) union_types[expr[meta]] = expr elif 'alternate' in expr: meta = 'alternate' check_keys(expr_elem, 'alternate', ['data'], ['if']) + normalize_members(expr['data']) elif 'struct' in expr: meta = 'struct' check_keys(expr_elem, 'struct', ['data'], ['base', 'if']) + normalize_members(expr['data']) struct_types[expr[meta]] = expr elif 'command' in expr: meta = 'command' check_keys(expr_elem, 'command', [], ['data', 'returns', 'gen', 'success-response', 'boxed', 'allow-oob', 'allow-preconfig', 'if']) + normalize_members(expr.get('data')) elif 'event' in expr: meta = 'event' check_keys(expr_elem, 'event', [], ['data', 'boxed', 'if']) + normalize_members(expr.get('data')) else: raise QAPISemError(expr_elem['info'], "Expression is missing metatype") @@ -1716,7 +1738,7 @@ class QAPISchema(object): return QAPISchemaObjectTypeMember(name, typ, optional) def _make_members(self, data, info): - return [self._make_member(key, value, info) + return [self._make_member(key, value['type'], info) for (key, value) in data.items()] def _def_struct_type(self, expr, info, doc): @@ -1752,11 +1774,11 @@ class QAPISchema(object): name, info, doc, ifcond, 'base', self._make_members(base, info)) if tag_name: - variants = [self._make_variant(key, value) + variants = [self._make_variant(key, value['type']) for (key, value) in data.items()] members = [] else: - variants = [self._make_simple_variant(key, value, info) + variants = [self._make_simple_variant(key, value['type'], info) for (key, value) in data.items()] enum = [{'name': v.name} for v in variants] typ = self._make_implicit_enum_type(name, info, ifcond, enum) @@ -1772,7 +1794,7 @@ class QAPISchema(object): name = expr['alternate'] data = expr['data'] ifcond = expr.get('if') - variants = [self._make_variant(key, value) + variants = [self._make_variant(key, value['type']) for (key, value) in data.items()] tag_member = QAPISchemaObjectTypeMember('type', 'QType', False) self._def_entity( diff --git a/tests/Makefile.include b/tests/Makefile.include index 3c9eea27fd..ea5d1e8787 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -318,6 +318,7 @@ qapi-schema += alternate-conflict-string.json qapi-schema += alternate-conflict-bool-string.json qapi-schema += alternate-conflict-num-string.json qapi-schema += alternate-empty.json +qapi-schema += alternate-invalid-dict.json qapi-schema += alternate-nested.json qapi-schema += alternate-unknown.json qapi-schema += args-alternate.json @@ -394,6 +395,7 @@ qapi-schema += escape-too-big.json qapi-schema += escape-too-short.json qapi-schema += event-boxed-empty.json qapi-schema += event-case.json +qapi-schema += event-member-invalid-dict.json qapi-schema += event-nest-struct.json qapi-schema += flat-union-array-branch.json qapi-schema += flat-union-bad-base.json @@ -403,6 +405,7 @@ qapi-schema += flat-union-base-union.json qapi-schema += flat-union-clash-member.json qapi-schema += flat-union-empty.json qapi-schema += flat-union-inline.json +qapi-schema += flat-union-inline-invalid-dict.json qapi-schema += flat-union-int-branch.json qapi-schema += flat-union-invalid-branch-key.json qapi-schema += flat-union-invalid-discriminator.json @@ -430,6 +433,7 @@ qapi-schema += missing-comma-list.json qapi-schema += missing-comma-object.json qapi-schema += missing-type.json qapi-schema += nested-struct-data.json +qapi-schema += nested-struct-data-invalid-dict.json qapi-schema += non-objects.json qapi-schema += oob-test.json qapi-schema += allow-preconfig-test.json @@ -460,6 +464,7 @@ qapi-schema += returns-whitelist.json qapi-schema += struct-base-clash-deep.json qapi-schema += struct-base-clash.json qapi-schema += struct-data-invalid.json +qapi-schema += struct-member-invalid-dict.json qapi-schema += struct-member-invalid.json qapi-schema += trailing-comma-list.json qapi-schema += trailing-comma-object.json @@ -471,6 +476,7 @@ qapi-schema += unicode-str.json qapi-schema += union-base-empty.json qapi-schema += union-base-no-discriminator.json qapi-schema += union-branch-case.json +qapi-schema += union-branch-invalid-dict.json qapi-schema += union-clash-branches.json qapi-schema += union-empty.json qapi-schema += union-invalid-base.json diff --git a/tests/qapi-schema/alternate-invalid-dict.err b/tests/qapi-schema/alternate-invalid-dict.err new file mode 100644 index 0000000000..631d46628e --- /dev/null +++ b/tests/qapi-schema/alternate-invalid-dict.err @@ -0,0 +1 @@ +tests/qapi-schema/alternate-invalid-dict.json:2: Key 'type' is missing from member 'two' of alternate 'Alt' diff --git a/tests/qapi-schema/alternate-invalid-dict.exit b/tests/qapi-schema/alternate-invalid-dict.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/alternate-invalid-dict.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/alternate-invalid-dict.json b/tests/qapi-schema/alternate-invalid-dict.json new file mode 100644 index 0000000000..8e0b2ac287 --- /dev/null +++ b/tests/qapi-schema/alternate-invalid-dict.json @@ -0,0 +1,4 @@ +# exploded member form must have a 'type' +{ 'alternate': 'Alt', + 'data': { 'one': 'str', + 'two': { 'if': 'foo' } } } diff --git a/tests/qapi-schema/alternate-invalid-dict.out b/tests/qapi-schema/alternate-invalid-dict.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/event-member-invalid-dict.err b/tests/qapi-schema/event-member-invalid-dict.err new file mode 100644 index 0000000000..1a57fa29b0 --- /dev/null +++ b/tests/qapi-schema/event-member-invalid-dict.err @@ -0,0 +1 @@ +tests/qapi-schema/event-member-invalid-dict.json:1: Key 'type' is missing from member 'a' of 'data' for event 'EVENT_A' diff --git a/tests/qapi-schema/event-member-invalid-dict.exit b/tests/qapi-schema/event-member-invalid-dict.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/event-member-invalid-dict.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/event-member-invalid-dict.json b/tests/qapi-schema/event-member-invalid-dict.json new file mode 100644 index 0000000000..ee6f3ecb6f --- /dev/null +++ b/tests/qapi-schema/event-member-invalid-dict.json @@ -0,0 +1,2 @@ +{ 'event': 'EVENT_A', + 'data': { 'a' : { 'string' : 'str', 'integer': 'int' }, 'b' : 'str' } } diff --git a/tests/qapi-schema/event-member-invalid-dict.out b/tests/qapi-schema/event-member-invalid-dict.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/event-nest-struct.json b/tests/qapi-schema/event-nest-struct.json index ee6f3ecb6f..355ddaeff1 100644 --- a/tests/qapi-schema/event-nest-struct.json +++ b/tests/qapi-schema/event-nest-struct.json @@ -1,2 +1,2 @@ { 'event': 'EVENT_A', - 'data': { 'a' : { 'string' : 'str', 'integer': 'int' }, 'b' : 'str' } } + 'data': { 'a' : { 'type' : { 'integer': 'int' } }, 'b' : 'str' } } diff --git a/tests/qapi-schema/flat-union-inline-invalid-dict.err b/tests/qapi-schema/flat-union-inline-invalid-dict.err new file mode 100644 index 0000000000..9c4c45b7f0 --- /dev/null +++ b/tests/qapi-schema/flat-union-inline-invalid-dict.err @@ -0,0 +1 @@ +tests/qapi-schema/flat-union-inline-invalid-dict.json:7: Key 'type' is missing from member 'value1' of union 'TestUnion' diff --git a/tests/qapi-schema/flat-union-inline-invalid-dict.exit b/tests/qapi-schema/flat-union-inline-invalid-dict.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/flat-union-inline-invalid-dict.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/flat-union-inline-invalid-dict.json b/tests/qapi-schema/flat-union-inline-invalid-dict.json new file mode 100644 index 0000000000..62c7cda617 --- /dev/null +++ b/tests/qapi-schema/flat-union-inline-invalid-dict.json @@ -0,0 +1,11 @@ +# we require branches to be a struct name +# TODO: should we allow anonymous inline branch types? +{ 'enum': 'TestEnum', + 'data': [ 'value1', 'value2' ] } +{ 'struct': 'Base', + 'data': { 'enum1': 'TestEnum', 'kind': 'str' } } +{ 'union': 'TestUnion', + 'base': 'Base', + 'discriminator': 'enum1', + 'data': { 'value1': { 'string': 'str' }, + 'value2': { 'integer': 'int' } } } diff --git a/tests/qapi-schema/flat-union-inline-invalid-dict.out b/tests/qapi-schema/flat-union-inline-invalid-dict.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/flat-union-inline.json b/tests/qapi-schema/flat-union-inline.json index 62c7cda617..a9b3ce3f0d 100644 --- a/tests/qapi-schema/flat-union-inline.json +++ b/tests/qapi-schema/flat-union-inline.json @@ -7,5 +7,5 @@ { 'union': 'TestUnion', 'base': 'Base', 'discriminator': 'enum1', - 'data': { 'value1': { 'string': 'str' }, + 'data': { 'value1': { 'type': {} }, 'value2': { 'integer': 'int' } } } diff --git a/tests/qapi-schema/nested-struct-data-invalid-dict.err b/tests/qapi-schema/nested-struct-data-invalid-dict.err new file mode 100644 index 0000000000..5bd364e8d9 --- /dev/null +++ b/tests/qapi-schema/nested-struct-data-invalid-dict.err @@ -0,0 +1 @@ +tests/qapi-schema/nested-struct-data-invalid-dict.json:2: Key 'type' is missing from member 'a' of 'data' for command 'foo' diff --git a/tests/qapi-schema/nested-struct-data-invalid-dict.exit b/tests/qapi-schema/nested-struct-data-invalid-dict.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/nested-struct-data-invalid-dict.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/nested-struct-data-invalid-dict.json b/tests/qapi-schema/nested-struct-data-invalid-dict.json new file mode 100644 index 0000000000..efbe773ded --- /dev/null +++ b/tests/qapi-schema/nested-struct-data-invalid-dict.json @@ -0,0 +1,3 @@ +# inline subtypes collide with our desired future use of defaults +{ 'command': 'foo', + 'data': { 'a' : { 'string' : 'str', 'integer': 'int' }, 'b' : 'str' } } diff --git a/tests/qapi-schema/nested-struct-data-invalid-dict.out b/tests/qapi-schema/nested-struct-data-invalid-dict.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/nested-struct-data.json b/tests/qapi-schema/nested-struct-data.json index efbe773ded..5b8a40cca3 100644 --- a/tests/qapi-schema/nested-struct-data.json +++ b/tests/qapi-schema/nested-struct-data.json @@ -1,3 +1,3 @@ # inline subtypes collide with our desired future use of defaults { 'command': 'foo', - 'data': { 'a' : { 'string' : 'str', 'integer': 'int' }, 'b' : 'str' } } + 'data': { 'a' : { 'type': {} }, 'b' : 'str' } } diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json index 8bfaf5aedd..40b162664d 100644 --- a/tests/qapi-schema/qapi-schema-test.json +++ b/tests/qapi-schema/qapi-schema-test.json @@ -11,7 +11,7 @@ 'guest-sync' ] } } { 'struct': 'TestStruct', - 'data': { 'integer': 'int', 'boolean': 'bool', 'string': 'str' } } + 'data': { 'integer': {'type': 'int'}, 'boolean': 'bool', 'string': 'str' } } # for testing enums { 'struct': 'NestedEnumsOne', @@ -77,7 +77,7 @@ { 'union': 'UserDefFlatUnion', 'base': 'UserDefUnionBase', # intentional forward reference 'discriminator': 'enum1', - 'data': { 'value1' : 'UserDefA', + 'data': { 'value1' : {'type': 'UserDefA'}, 'value2' : 'UserDefB', 'value3' : 'UserDefB' # 'value4' defaults to empty @@ -98,7 +98,7 @@ { 'struct': 'WrapAlternate', 'data': { 'alt': 'UserDefAlternate' } } { 'alternate': 'UserDefAlternate', - 'data': { 'udfu': 'UserDefFlatUnion', 'e': 'EnumOne', 'i': 'int', + 'data': { 'udfu': {'type': 'UserDefFlatUnion'}, 'e': 'EnumOne', 'i': 'int', 'n': 'null' } } { 'struct': 'UserDefC', @@ -134,7 +134,7 @@ { 'command': 'user_def_cmd', 'data': {} } { 'command': 'user_def_cmd1', 'data': {'ud1a': 'UserDefOne'} } { 'command': 'user_def_cmd2', - 'data': {'ud1a': 'UserDefOne', '*ud1b': 'UserDefOne'}, + 'data': {'ud1a': {'type': 'UserDefOne'}, '*ud1b': 'UserDefOne'}, 'returns': 'UserDefTwo' } { 'command': 'cmd-success-response', 'data': {}, 'success-response': false } @@ -166,7 +166,7 @@ # testing event { 'struct': 'EventStructOne', - 'data': { 'struct1': 'UserDefOne', 'string': 'str', '*enum2': 'EnumOne' } } + 'data': { 'struct1': {'type': 'UserDefOne'}, 'string': 'str', '*enum2': 'EnumOne' } } { 'event': 'EVENT_A' } { 'event': 'EVENT_B', diff --git a/tests/qapi-schema/struct-member-invalid-dict.err b/tests/qapi-schema/struct-member-invalid-dict.err new file mode 100644 index 0000000000..6a765bc668 --- /dev/null +++ b/tests/qapi-schema/struct-member-invalid-dict.err @@ -0,0 +1 @@ +tests/qapi-schema/struct-member-invalid-dict.json:2: Key 'type' is missing from member '*a' of 'data' for struct 'foo' diff --git a/tests/qapi-schema/struct-member-invalid-dict.exit b/tests/qapi-schema/struct-member-invalid-dict.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/struct-member-invalid-dict.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/struct-member-invalid-dict.json b/tests/qapi-schema/struct-member-invalid-dict.json new file mode 100644 index 0000000000..9fe0d455a9 --- /dev/null +++ b/tests/qapi-schema/struct-member-invalid-dict.json @@ -0,0 +1,3 @@ +# Long form of member must have a value member 'type' +{ 'struct': 'foo', + 'data': { '*a': { 'case': 'foo' } } } diff --git a/tests/qapi-schema/struct-member-invalid-dict.out b/tests/qapi-schema/struct-member-invalid-dict.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/union-branch-invalid-dict.err b/tests/qapi-schema/union-branch-invalid-dict.err new file mode 100644 index 0000000000..89f9b36791 --- /dev/null +++ b/tests/qapi-schema/union-branch-invalid-dict.err @@ -0,0 +1 @@ +tests/qapi-schema/union-branch-invalid-dict.json:2: Key 'type' is missing from member 'integer' of union 'UnionInvalidBranch' diff --git a/tests/qapi-schema/union-branch-invalid-dict.exit b/tests/qapi-schema/union-branch-invalid-dict.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/union-branch-invalid-dict.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/union-branch-invalid-dict.json b/tests/qapi-schema/union-branch-invalid-dict.json new file mode 100644 index 0000000000..9778598dbd --- /dev/null +++ b/tests/qapi-schema/union-branch-invalid-dict.json @@ -0,0 +1,4 @@ +# Long form of member must have a value member 'type' +{ 'union': 'UnionInvalidBranch', + 'data': { 'integer': { 'if': 'foo'}, + 's8': 'int8' } } From patchwork Thu Dec 13 18:43:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 1013081 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43G3Hr60kTz9s3Z for ; Fri, 14 Dec 2018 06:13:44 +1100 (AEDT) Received: from localhost ([::1]:54403 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXWQY-0006XW-1I for incoming@patchwork.ozlabs.org; Thu, 13 Dec 2018 14:13:42 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53428) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVyB-00066f-F5 for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:26 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXVy7-0003n5-1J for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:21 -0500 Received: from mx1.redhat.com ([209.132.183.28]:36094) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gXVy0-0001ic-JZ for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:15 -0500 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 448FC307EA84 for ; Thu, 13 Dec 2018 18:43:50 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-56.ams2.redhat.com [10.36.116.56]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 3166961292; Thu, 13 Dec 2018 18:43:47 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id AB3F11132C16; Thu, 13 Dec 2018 19:43:40 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2018 19:43:32 +0100 Message-Id: <20181213184340.24037-25-armbru@redhat.com> In-Reply-To: <20181213184340.24037-1-armbru@redhat.com> References: <20181213184340.24037-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.44]); Thu, 13 Dec 2018 18:43:50 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 24/32] qapi: Add 'if' to implicit struct members X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau The generated code is for now *unconditional*. Later patches generate the conditionals. Note that union discriminators may not have 'if' conditionals. Signed-off-by: Marc-André Lureau Reviewed-by: Markus Armbruster Message-Id: <20181213123724.4866-14-marcandre.lureau@redhat.com> Message-Id: <20181213123724.4866-15-marcandre.lureau@redhat.com> [Patches squashed, commit message tweaked] Signed-off-by: Markus Armbruster --- docs/devel/qapi-code-gen.txt | 10 ++++++++++ scripts/qapi/common.py | 18 +++++++++++------- tests/Makefile.include | 1 + .../flat-union-invalid-if-discriminator.err | 1 + .../flat-union-invalid-if-discriminator.exit | 1 + .../flat-union-invalid-if-discriminator.json | 17 +++++++++++++++++ .../flat-union-invalid-if-discriminator.out | 0 tests/qapi-schema/qapi-schema-test.json | 12 +++++++++--- tests/qapi-schema/qapi-schema-test.out | 5 +++++ tests/qapi-schema/test-qapi.py | 1 + 10 files changed, 56 insertions(+), 10 deletions(-) create mode 100644 tests/qapi-schema/flat-union-invalid-if-discriminator.err create mode 100644 tests/qapi-schema/flat-union-invalid-if-discriminator.exit create mode 100644 tests/qapi-schema/flat-union-invalid-if-discriminator.json create mode 100644 tests/qapi-schema/flat-union-invalid-if-discriminator.out diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt index 7ba9066eac..3895808b4a 100644 --- a/docs/devel/qapi-code-gen.txt +++ b/docs/devel/qapi-code-gen.txt @@ -752,6 +752,16 @@ gets its generated code guarded like this: #endif /* defined(HAVE_BAR) */ #endif /* defined(CONFIG_FOO) */ +Where a member can be defined with a single string value for its type, +it is also possible to supply a dictionary instead with both 'type' +and 'if' keys. (TODO: union and alternate) + +Example: a conditional 'bar' member + +{ 'struct': 'IfStruct', 'data': + { 'foo': 'int', + 'bar': { 'type': 'int', 'if': 'defined(IFCOND)'} } } + An enum value can be replaced by a dictionary with a 'name' and a 'if' key. diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index cdfe2bf2a5..98e9d6f109 100644 --- a/scripts/qapi/common.py +++ b/scripts/qapi/common.py @@ -705,7 +705,7 @@ def check_type(info, source, value, allow_array=False, # Todo: allow dictionaries to represent default values of # an optional argument. check_known_keys(info, "member '%s' of %s" % (key, source), - arg, ['type'], []) + arg, ['type'], ['if']) check_type(info, "Member '%s' of %s" % (key, source), arg['type'], allow_array=True, allow_metas=['built-in', 'union', 'alternate', 'struct', @@ -784,6 +784,10 @@ def check_union(expr, info): "Discriminator '%s' is not a member of base " "struct '%s'" % (discriminator, base)) + if discriminator_value.get('if'): + raise QAPISemError(info, 'The discriminator %s.%s for union %s ' + 'must not be conditional' % + (base, discriminator, name)) enum_define = enum_types.get(discriminator_value['type']) allow_metas = ['struct'] # Do not allow string discriminator @@ -1412,8 +1416,8 @@ class QAPISchemaMember(object): class QAPISchemaObjectTypeMember(QAPISchemaMember): - def __init__(self, name, typ, optional): - QAPISchemaMember.__init__(self, name) + def __init__(self, name, typ, optional, ifcond=None): + QAPISchemaMember.__init__(self, name, ifcond) assert isinstance(typ, str) assert isinstance(optional, bool) self._type_name = typ @@ -1727,7 +1731,7 @@ class QAPISchema(object): name, info, doc, ifcond, self._make_enum_members(data), prefix)) - def _make_member(self, name, typ, info): + def _make_member(self, name, typ, ifcond, info): optional = False if name.startswith('*'): name = name[1:] @@ -1735,10 +1739,10 @@ class QAPISchema(object): if isinstance(typ, list): assert len(typ) == 1 typ = self._make_array_type(typ[0], info) - return QAPISchemaObjectTypeMember(name, typ, optional) + return QAPISchemaObjectTypeMember(name, typ, optional, ifcond) def _make_members(self, data, info): - return [self._make_member(key, value['type'], info) + return [self._make_member(key, value['type'], value.get('if'), info) for (key, value) in data.items()] def _def_struct_type(self, expr, info, doc): @@ -1759,7 +1763,7 @@ class QAPISchema(object): typ = self._make_array_type(typ[0], info) typ = self._make_implicit_object_type( typ, info, None, self.lookup_type(typ), - 'wrapper', [self._make_member('data', typ, info)]) + 'wrapper', [self._make_member('data', typ, None, info)]) return QAPISchemaObjectTypeVariant(case, typ) def _def_union_type(self, expr, info, doc): diff --git a/tests/Makefile.include b/tests/Makefile.include index ea5d1e8787..3f5a1d0c30 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -409,6 +409,7 @@ qapi-schema += flat-union-inline-invalid-dict.json qapi-schema += flat-union-int-branch.json qapi-schema += flat-union-invalid-branch-key.json qapi-schema += flat-union-invalid-discriminator.json +qapi-schema += flat-union-invalid-if-discriminator.json qapi-schema += flat-union-no-base.json qapi-schema += flat-union-optional-discriminator.json qapi-schema += flat-union-string-discriminator.json diff --git a/tests/qapi-schema/flat-union-invalid-if-discriminator.err b/tests/qapi-schema/flat-union-invalid-if-discriminator.err new file mode 100644 index 0000000000..0c94c9860d --- /dev/null +++ b/tests/qapi-schema/flat-union-invalid-if-discriminator.err @@ -0,0 +1 @@ +tests/qapi-schema/flat-union-invalid-if-discriminator.json:13: The discriminator TestBase.enum1 for union TestUnion must not be conditional diff --git a/tests/qapi-schema/flat-union-invalid-if-discriminator.exit b/tests/qapi-schema/flat-union-invalid-if-discriminator.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/flat-union-invalid-if-discriminator.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/flat-union-invalid-if-discriminator.json b/tests/qapi-schema/flat-union-invalid-if-discriminator.json new file mode 100644 index 0000000000..618ec36396 --- /dev/null +++ b/tests/qapi-schema/flat-union-invalid-if-discriminator.json @@ -0,0 +1,17 @@ +{ 'enum': 'TestEnum', + 'data': [ 'value1', 'value2' ] } + +{ 'struct': 'TestBase', + 'data': { 'enum1': { 'type': 'TestEnum', 'if': 'FOO' } } } + +{ 'struct': 'TestTypeA', + 'data': { 'string': 'str' } } + +{ 'struct': 'TestTypeB', + 'data': { 'integer': 'int' } } + +{ 'union': 'TestUnion', + 'base': 'TestBase', + 'discriminator': 'enum1', + 'data': { 'value1': 'TestTypeA', + 'value2': 'TestTypeB' } } diff --git a/tests/qapi-schema/flat-union-invalid-if-discriminator.out b/tests/qapi-schema/flat-union-invalid-if-discriminator.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json index 40b162664d..c46f3b5732 100644 --- a/tests/qapi-schema/qapi-schema-test.json +++ b/tests/qapi-schema/qapi-schema-test.json @@ -201,7 +201,9 @@ # test 'if' condition handling -{ 'struct': 'TestIfStruct', 'data': { 'foo': 'int' }, +{ 'struct': 'TestIfStruct', 'data': + { 'foo': 'int', + 'bar': { 'type': 'int', 'if': 'defined(TEST_IF_STRUCT_BAR)'} }, 'if': 'defined(TEST_IF_STRUCT)' } { 'enum': 'TestIfEnum', 'data': @@ -220,11 +222,15 @@ { 'command': 'TestIfAlternateCmd', 'data': { 'alt_cmd_arg': 'TestIfAlternate' }, 'if': 'defined(TEST_IF_ALT)' } -{ 'command': 'TestIfCmd', 'data': { 'foo': 'TestIfStruct', 'bar': 'TestIfEnum' }, +{ 'command': 'TestIfCmd', 'data': + { 'foo': 'TestIfStruct', + 'bar': { 'type': 'TestIfEnum', 'if': 'defined(TEST_IF_CMD_BAR)' } }, 'returns': 'UserDefThree', 'if': ['defined(TEST_IF_CMD)', 'defined(TEST_IF_STRUCT)'] } { 'command': 'TestCmdReturnDefThree', 'returns': 'UserDefThree' } -{ 'event': 'TestIfEvent', 'data': { 'foo': 'TestIfStruct' }, +{ 'event': 'TestIfEvent', 'data': + { 'foo': 'TestIfStruct', + 'bar': { 'type': 'TestIfEnum', 'if': 'defined(TEST_IF_EVT_BAR)' } }, 'if': 'defined(TEST_IF_EVT) && defined(TEST_IF_STRUCT)' } diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out index d90d987651..7987b23403 100644 --- a/tests/qapi-schema/qapi-schema-test.out +++ b/tests/qapi-schema/qapi-schema-test.out @@ -268,6 +268,8 @@ command __org.qemu_x-command q_obj___org.qemu_x-command-arg -> __org.qemu_x-Unio gen=True success_response=True boxed=False oob=False preconfig=False object TestIfStruct member foo: int optional=False + member bar: int optional=False + if ['defined(TEST_IF_STRUCT_BAR)'] if ['defined(TEST_IF_STRUCT)'] enum TestIfEnum member foo @@ -304,6 +306,7 @@ command TestIfAlternateCmd q_obj_TestIfAlternateCmd-arg -> None object q_obj_TestIfCmd-arg member foo: TestIfStruct optional=False member bar: TestIfEnum optional=False + if ['defined(TEST_IF_CMD_BAR)'] if ['defined(TEST_IF_CMD)', 'defined(TEST_IF_STRUCT)'] command TestIfCmd q_obj_TestIfCmd-arg -> UserDefThree gen=True success_response=True boxed=False oob=False preconfig=False @@ -312,6 +315,8 @@ command TestCmdReturnDefThree None -> UserDefThree gen=True success_response=True boxed=False oob=False preconfig=False object q_obj_TestIfEvent-arg member foo: TestIfStruct optional=False + member bar: TestIfEnum optional=False + if ['defined(TEST_IF_EVT_BAR)'] if ['defined(TEST_IF_EVT) && defined(TEST_IF_STRUCT)'] event TestIfEvent q_obj_TestIfEvent-arg boxed=False diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py index aadf252d9d..27081cb50c 100644 --- a/tests/qapi-schema/test-qapi.py +++ b/tests/qapi-schema/test-qapi.py @@ -39,6 +39,7 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor): for m in members: print(' member %s: %s optional=%s' % (m.name, m.type.name, m.optional)) + self._print_if(m.ifcond, 8) self._print_variants(variants) self._print_if(ifcond) From patchwork Thu Dec 13 18:43:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 1013062 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43G30L3d74z9s3Z for ; Fri, 14 Dec 2018 06:00:18 +1100 (AEDT) Received: from localhost ([::1]:54309 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXWDX-0002mP-Tn for incoming@patchwork.ozlabs.org; Thu, 13 Dec 2018 14:00:15 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53409) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVy8-00063F-25 for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:21 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXVy2-0003SU-DB for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:18 -0500 Received: from mx1.redhat.com ([209.132.183.28]:40184) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gXVxt-0001iE-Ds for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:07 -0500 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 204FD308429C for ; Thu, 13 Dec 2018 18:43:50 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-56.ams2.redhat.com [10.36.116.56]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 9B18C5D6A9; Thu, 13 Dec 2018 18:43:47 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id AF0721132C17; Thu, 13 Dec 2018 19:43:40 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2018 19:43:33 +0100 Message-Id: <20181213184340.24037-26-armbru@redhat.com> In-Reply-To: <20181213184340.24037-1-armbru@redhat.com> References: <20181213184340.24037-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.40]); Thu, 13 Dec 2018 18:43:50 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 25/32] qapi: add 'if' to union members X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Add 'if' key to union members: { 'union': 'TestIfUnion', 'data': 'mem': { 'type': 'str', 'if': 'COND'} } The generated code remains unconditional for now. Later patches generate the conditionals. Signed-off-by: Marc-André Lureau Reviewed-by: Markus Armbruster Message-Id: <20181213123724.4866-16-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster --- docs/devel/qapi-code-gen.txt | 2 +- scripts/qapi/common.py | 15 ++++++++------- tests/qapi-schema/qapi-schema-test.json | 4 +++- tests/qapi-schema/qapi-schema-test.out | 4 ++++ tests/qapi-schema/test-qapi.py | 1 + 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt index 3895808b4a..0a0e53ede5 100644 --- a/docs/devel/qapi-code-gen.txt +++ b/docs/devel/qapi-code-gen.txt @@ -754,7 +754,7 @@ gets its generated code guarded like this: Where a member can be defined with a single string value for its type, it is also possible to supply a dictionary instead with both 'type' -and 'if' keys. (TODO: union and alternate) +and 'if' keys. (TODO: alternate) Example: a conditional 'bar' member diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index 98e9d6f109..44fe8868ed 100644 --- a/scripts/qapi/common.py +++ b/scripts/qapi/common.py @@ -803,7 +803,7 @@ def check_union(expr, info): check_name(info, "Member of union '%s'" % name, key) check_known_keys(info, "member '%s' of union '%s'" % (key, name), - value, ['type'], []) + value, ['type'], ['if']) # Each value must name a known type check_type(info, "Member '%s' of union '%s'" % (key, name), value['type'], @@ -1483,8 +1483,8 @@ class QAPISchemaObjectTypeVariants(object): class QAPISchemaObjectTypeVariant(QAPISchemaObjectTypeMember): role = 'branch' - def __init__(self, name, typ): - QAPISchemaObjectTypeMember.__init__(self, name, typ, False) + def __init__(self, name, typ, ifcond=None): + QAPISchemaObjectTypeMember.__init__(self, name, typ, False, ifcond) class QAPISchemaAlternateType(QAPISchemaType): @@ -1757,14 +1757,14 @@ class QAPISchema(object): def _make_variant(self, case, typ): return QAPISchemaObjectTypeVariant(case, typ) - def _make_simple_variant(self, case, typ, info): + def _make_simple_variant(self, case, typ, ifcond, info): if isinstance(typ, list): assert len(typ) == 1 typ = self._make_array_type(typ[0], info) typ = self._make_implicit_object_type( typ, info, None, self.lookup_type(typ), 'wrapper', [self._make_member('data', typ, None, info)]) - return QAPISchemaObjectTypeVariant(case, typ) + return QAPISchemaObjectTypeVariant(case, typ, ifcond) def _def_union_type(self, expr, info, doc): name = expr['union'] @@ -1782,9 +1782,10 @@ class QAPISchema(object): for (key, value) in data.items()] members = [] else: - variants = [self._make_simple_variant(key, value['type'], info) + variants = [self._make_simple_variant(key, value['type'], + value.get('if'), info) for (key, value) in data.items()] - enum = [{'name': v.name} for v in variants] + enum = [{'name': v.name, 'if': v.ifcond} for v in variants] typ = self._make_implicit_enum_type(name, info, ifcond, enum) tag_member = QAPISchemaObjectTypeMember('type', typ, False) members = [tag_member] diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json index c46f3b5732..a33eff8f86 100644 --- a/tests/qapi-schema/qapi-schema-test.json +++ b/tests/qapi-schema/qapi-schema-test.json @@ -210,7 +210,9 @@ [ 'foo', { 'name' : 'bar', 'if': 'defined(TEST_IF_ENUM_BAR)' } ], 'if': 'defined(TEST_IF_ENUM)' } -{ 'union': 'TestIfUnion', 'data': { 'foo': 'TestStruct' }, +{ 'union': 'TestIfUnion', 'data': + { 'foo': 'TestStruct', + 'union_bar': { 'type': 'str', 'if': 'defined(TEST_IF_UNION_BAR)'} }, 'if': 'defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)' } { 'command': 'TestIfUnionCmd', 'data': { 'union_cmd_arg': 'TestIfUnion' }, diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out index 7987b23403..f4c11f1e6a 100644 --- a/tests/qapi-schema/qapi-schema-test.out +++ b/tests/qapi-schema/qapi-schema-test.out @@ -280,11 +280,15 @@ object q_obj_TestStruct-wrapper member data: TestStruct optional=False enum TestIfUnionKind member foo + member union_bar + if ['defined(TEST_IF_UNION_BAR)'] if ['defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)'] object TestIfUnion member type: TestIfUnionKind optional=False tag type case foo: q_obj_TestStruct-wrapper + case union_bar: q_obj_str-wrapper + if ['defined(TEST_IF_UNION_BAR)'] if ['defined(TEST_IF_UNION) && defined(TEST_IF_STRUCT)'] object q_obj_TestIfUnionCmd-arg member union_cmd_arg: TestIfUnion optional=False diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py index 27081cb50c..d592854601 100644 --- a/tests/qapi-schema/test-qapi.py +++ b/tests/qapi-schema/test-qapi.py @@ -68,6 +68,7 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor): print(' tag %s' % variants.tag_member.name) for v in variants.variants: print(' case %s: %s' % (v.name, v.type.name)) + QAPISchemaTestVisitor._print_if(v.ifcond, indent=8) @staticmethod def _print_if(ifcond, indent=4): From patchwork Thu Dec 13 18:43:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 1013080 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43G3F022Qxz9s3Z for ; Fri, 14 Dec 2018 06:11:16 +1100 (AEDT) Received: from localhost ([::1]:54382 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXWO9-0004Fn-Oc for incoming@patchwork.ozlabs.org; Thu, 13 Dec 2018 14:11:13 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53393) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVy7-00062I-1l for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:20 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXVxx-00036Q-98 for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:14 -0500 Received: from mx1.redhat.com ([209.132.183.28]:38365) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gXVxr-0001dC-Om for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:05 -0500 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C77E931256B2 for ; Thu, 13 Dec 2018 18:43:48 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-56.ams2.redhat.com [10.36.116.56]) by smtp.corp.redhat.com (Postfix) with ESMTPS id A350860139; Thu, 13 Dec 2018 18:43:47 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id B2C571132C18; Thu, 13 Dec 2018 19:43:40 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2018 19:43:34 +0100 Message-Id: <20181213184340.24037-27-armbru@redhat.com> In-Reply-To: <20181213184340.24037-1-armbru@redhat.com> References: <20181213184340.24037-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.46]); Thu, 13 Dec 2018 18:43:48 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 26/32] qapi: add 'if' to alternate members X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Add 'if' key to alternate members: { 'alternate': 'TestIfAlternate', 'data': { 'alt': { 'type': 'TestStruct', 'if': 'COND' } } } Generated code is not changed by this patch but with "qapi: add #if conditions to generated code". Signed-off-by: Marc-André Lureau Reviewed-by: Markus Armbruster Message-Id: <20181213123724.4866-17-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster --- docs/devel/qapi-code-gen.txt | 2 +- scripts/qapi/common.py | 10 +++++----- tests/qapi-schema/qapi-schema-test.json | 4 +++- tests/qapi-schema/qapi-schema-test.out | 1 + 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt index 0a0e53ede5..43bd853e69 100644 --- a/docs/devel/qapi-code-gen.txt +++ b/docs/devel/qapi-code-gen.txt @@ -754,7 +754,7 @@ gets its generated code guarded like this: Where a member can be defined with a single string value for its type, it is also possible to supply a dictionary instead with both 'type' -and 'if' keys. (TODO: alternate) +and 'if' keys. Example: a conditional 'bar' member diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index 44fe8868ed..17707b6de7 100644 --- a/scripts/qapi/common.py +++ b/scripts/qapi/common.py @@ -833,7 +833,7 @@ def check_alternate(expr, info): check_name(info, "Member of alternate '%s'" % name, key) check_known_keys(info, "member '%s' of alternate '%s'" % (key, name), - value, ['type'], []) + value, ['type'], ['if']) typ = value['type'] # Ensure alternates have no type conflicts. @@ -1754,8 +1754,8 @@ class QAPISchema(object): self._make_members(data, info), None)) - def _make_variant(self, case, typ): - return QAPISchemaObjectTypeVariant(case, typ) + def _make_variant(self, case, typ, ifcond): + return QAPISchemaObjectTypeVariant(case, typ, ifcond) def _make_simple_variant(self, case, typ, ifcond, info): if isinstance(typ, list): @@ -1778,7 +1778,7 @@ class QAPISchema(object): name, info, doc, ifcond, 'base', self._make_members(base, info)) if tag_name: - variants = [self._make_variant(key, value['type']) + variants = [self._make_variant(key, value['type'], value.get('if')) for (key, value) in data.items()] members = [] else: @@ -1799,7 +1799,7 @@ class QAPISchema(object): name = expr['alternate'] data = expr['data'] ifcond = expr.get('if') - variants = [self._make_variant(key, value['type']) + variants = [self._make_variant(key, value['type'], value.get('if')) for (key, value) in data.items()] tag_member = QAPISchemaObjectTypeMember('type', 'QType', False) self._def_entity( diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json index a33eff8f86..cb0857df52 100644 --- a/tests/qapi-schema/qapi-schema-test.json +++ b/tests/qapi-schema/qapi-schema-test.json @@ -218,7 +218,9 @@ { 'command': 'TestIfUnionCmd', 'data': { 'union_cmd_arg': 'TestIfUnion' }, 'if': 'defined(TEST_IF_UNION)' } -{ 'alternate': 'TestIfAlternate', 'data': { 'foo': 'int', 'bar': 'TestStruct' }, +{ 'alternate': 'TestIfAlternate', 'data': + { 'foo': 'int', + 'bar': { 'type': 'TestStruct', 'if': 'defined(TEST_IF_ALT_BAR)'} }, 'if': 'defined(TEST_IF_ALT) && defined(TEST_IF_STRUCT)' } { 'command': 'TestIfAlternateCmd', 'data': { 'alt_cmd_arg': 'TestIfAlternate' }, diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out index f4c11f1e6a..9464101d26 100644 --- a/tests/qapi-schema/qapi-schema-test.out +++ b/tests/qapi-schema/qapi-schema-test.out @@ -300,6 +300,7 @@ alternate TestIfAlternate tag type case foo: int case bar: TestStruct + if ['defined(TEST_IF_ALT_BAR)'] if ['defined(TEST_IF_ALT) && defined(TEST_IF_STRUCT)'] object q_obj_TestIfAlternateCmd-arg member alt_cmd_arg: TestIfAlternate optional=False From patchwork Thu Dec 13 18:43:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 1013059 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43G2xP4ZQxz9s3Z for ; Fri, 14 Dec 2018 05:57:45 +1100 (AEDT) Received: from localhost ([::1]:54297 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXWB5-0008TS-5I for incoming@patchwork.ozlabs.org; Thu, 13 Dec 2018 13:57:43 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53198) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVxo-0005hb-HE for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:02 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXVxj-0002A5-N3 for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:59 -0500 Received: from mx1.redhat.com ([209.132.183.28]:36084) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gXVxj-0001eP-Bv for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:55 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 726DC30832D2 for ; Thu, 13 Dec 2018 18:43:49 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-56.ams2.redhat.com [10.36.116.56]) by smtp.corp.redhat.com (Postfix) with ESMTPS id C12E7648DC; Thu, 13 Dec 2018 18:43:47 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id B68731132C2A; Thu, 13 Dec 2018 19:43:40 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2018 19:43:35 +0100 Message-Id: <20181213184340.24037-28-armbru@redhat.com> In-Reply-To: <20181213184340.24037-1-armbru@redhat.com> References: <20181213184340.24037-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.44]); Thu, 13 Dec 2018 18:43:49 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 27/32] qapi: add #if conditions to generated code members X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Wrap generated enum and struct members and their supporting code with We do enum and struct in a single patch because union tag enum and the associated variants tie them together, and dealing with that to split the patch doesn't seem worthwhile. Signed-off-by: Marc-André Lureau Reviewed-by: Markus Armbruster Message-Id: <20181213123724.4866-18-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster --- scripts/qapi/common.py | 4 ++++ scripts/qapi/introspect.py | 14 ++++++++++---- scripts/qapi/types.py | 4 ++++ scripts/qapi/visit.py | 6 ++++++ 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index 17707b6de7..8c2d97369e 100644 --- a/scripts/qapi/common.py +++ b/scripts/qapi/common.py @@ -2078,11 +2078,13 @@ const QEnumLookup %(c_name)s_lookup = { ''', c_name=c_name(name)) for m in members: + ret += gen_if(m.ifcond) index = c_enum_const(name, m.name, prefix) ret += mcgen(''' [%(index)s] = "%(name)s", ''', index=index, name=m.name) + ret += gen_endif(m.ifcond) ret += mcgen(''' }, @@ -2104,10 +2106,12 @@ typedef enum %(c_name)s { c_name=c_name(name)) for m in enum_members: + ret += gen_if(m.ifcond) ret += mcgen(''' %(c_enum)s, ''', c_enum=c_enum_const(name, m.name, prefix)) + ret += gen_endif(m.ifcond) ret += mcgen(''' } %(c_name)s; diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py index 417625d54b..f7f2ca07e4 100644 --- a/scripts/qapi/introspect.py +++ b/scripts/qapi/introspect.py @@ -162,6 +162,8 @@ const QLitObject %(c_name)s = %(c_string)s; ret = {'name': member.name, 'type': self._use_type(member.type)} if member.optional: ret['default'] = None + if member.ifcond: + ret = (ret, {'if': member.ifcond}) return ret def _gen_variants(self, tag_name, variants): @@ -169,14 +171,17 @@ const QLitObject %(c_name)s = %(c_string)s; 'variants': [self._gen_variant(v) for v in variants]} def _gen_variant(self, variant): - return {'case': variant.name, 'type': self._use_type(variant.type)} + return ({'case': variant.name, 'type': self._use_type(variant.type)}, + {'if': variant.ifcond}) def visit_builtin_type(self, name, info, json_type): self._gen_qlit(name, 'builtin', {'json-type': json_type}, []) def visit_enum_type(self, name, info, ifcond, members, prefix): self._gen_qlit(name, 'enum', - {'values': [m.name for m in members]}, ifcond) + {'values': + [(m.name, {'if': m.ifcond}) for m in members]}, + ifcond) def visit_array_type(self, name, info, ifcond, element_type): element = self._use_type(element_type) @@ -192,8 +197,9 @@ const QLitObject %(c_name)s = %(c_string)s; def visit_alternate_type(self, name, info, ifcond, variants): self._gen_qlit(name, 'alternate', - {'members': [{'type': self._use_type(m.type)} - for m in variants.variants]}, ifcond) + {'members': [ + ({'type': self._use_type(m.type)}, {'if': m.ifcond}) + for m in variants.variants]}, ifcond) def visit_command(self, name, info, ifcond, arg_type, ret_type, gen, success_response, boxed, allow_oob, allow_preconfig): diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py index e8d22c5081..62d4cf9f95 100644 --- a/scripts/qapi/types.py +++ b/scripts/qapi/types.py @@ -43,6 +43,7 @@ struct %(c_name)s { def gen_struct_members(members): ret = '' for memb in members: + ret += gen_if(memb.ifcond) if memb.optional: ret += mcgen(''' bool has_%(c_name)s; @@ -52,6 +53,7 @@ def gen_struct_members(members): %(c_type)s %(c_name)s; ''', c_type=memb.type.c_type(), c_name=c_name(memb.name)) + ret += gen_endif(memb.ifcond) return ret @@ -131,11 +133,13 @@ def gen_variants(variants): for var in variants.variants: if var.type.name == 'q_empty': continue + ret += gen_if(var.ifcond) ret += mcgen(''' %(c_type)s %(c_name)s; ''', c_type=var.type.c_unboxed_type(), c_name=c_name(var.name)) + ret += gen_endif(var.ifcond) ret += mcgen(''' } u; diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py index 24f85a2e85..82eab72b21 100644 --- a/scripts/qapi/visit.py +++ b/scripts/qapi/visit.py @@ -54,6 +54,7 @@ void visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp) c_type=base.c_name()) for memb in members: + ret += gen_if(memb.ifcond) if memb.optional: ret += mcgen(''' if (visit_optional(v, "%(name)s", &obj->has_%(c_name)s)) { @@ -73,6 +74,7 @@ void visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp) ret += mcgen(''' } ''') + ret += gen_endif(memb.ifcond) if variants: ret += mcgen(''' @@ -84,6 +86,7 @@ void visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp) case_str = c_enum_const(variants.tag_member.type.name, var.name, variants.tag_member.type.prefix) + ret += gen_if(var.ifcond) if var.type.name == 'q_empty': # valid variant and nothing to do ret += mcgen(''' @@ -100,6 +103,7 @@ void visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp) case=case_str, c_type=var.type.c_name(), c_name=c_name(var.name)) + ret += gen_endif(var.ifcond) ret += mcgen(''' default: abort(); @@ -190,6 +194,7 @@ void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error c_name=c_name(name)) for var in variants.variants: + ret += gen_if(var.ifcond) ret += mcgen(''' case %(case)s: ''', @@ -217,6 +222,7 @@ void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error ret += mcgen(''' break; ''') + ret += gen_endif(var.ifcond) ret += mcgen(''' case QTYPE_NONE: From patchwork Thu Dec 13 18:43:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 1013063 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43G30b4xv1z9s9G for ; Fri, 14 Dec 2018 06:00:31 +1100 (AEDT) Received: from localhost ([::1]:54311 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXWDl-0002xP-7Q for incoming@patchwork.ozlabs.org; Thu, 13 Dec 2018 14:00:29 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53194) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVxo-0005hZ-Gt for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:02 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXVxk-0002Bz-6P for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:59 -0500 Received: from mx1.redhat.com ([209.132.183.28]:34312) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gXVxj-0001iW-Hd for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:55 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 40AF3300238C for ; Thu, 13 Dec 2018 18:43:50 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-56.ams2.redhat.com [10.36.116.56]) by smtp.corp.redhat.com (Postfix) with ESMTPS id CA3F41057042; Thu, 13 Dec 2018 18:43:47 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id BA4101132C2C; Thu, 13 Dec 2018 19:43:40 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2018 19:43:36 +0100 Message-Id: <20181213184340.24037-29-armbru@redhat.com> In-Reply-To: <20181213184340.24037-1-armbru@redhat.com> References: <20181213184340.24037-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.47]); Thu, 13 Dec 2018 18:43:50 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 28/32] qapi: add 'If:' condition to enum values documentation X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Use a common function to generate the "If:..." line. While at it, get rid of the existing \n\n (no idea why it was there). Use a line-break in member description, this seems to look slightly better in the plaintext version. Signed-off-by: Marc-André Lureau Message-Id: <20181213123724.4866-19-marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster --- scripts/qapi/doc.py | 25 ++++++++++++++++--------- tests/qapi-schema/doc-good.json | 4 +++- tests/qapi-schema/doc-good.out | 1 + tests/qapi-schema/doc-good.texi | 2 +- 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/scripts/qapi/doc.py b/scripts/qapi/doc.py index 76cb186ff9..ab36b9dec6 100755 --- a/scripts/qapi/doc.py +++ b/scripts/qapi/doc.py @@ -126,19 +126,27 @@ def texi_body(doc): return texi_format(doc.body.text) -def texi_enum_value(value): +def texi_if(ifcond, prefix='\n', suffix='\n'): + """Format the #if condition""" + if not ifcond: + return '' + return '%s@b{If:} @code{%s}%s' % (prefix, ', '.join(ifcond), suffix) + + +def texi_enum_value(value, desc, suffix): """Format a table of members item for an enumeration value""" - return '@item @code{%s}\n' % value.name + return '@item @code{%s}\n%s%s' % ( + value.name, desc, texi_if(value.ifcond, prefix='@*')) -def texi_member(member, suffix=''): +def texi_member(member, desc, suffix): """Format a table of members item for an object type member""" typ = member.type.doc_type() membertype = ': ' + typ if typ else '' - return '@item @code{%s%s}%s%s\n' % ( + return '@item @code{%s%s}%s%s\n%s' % ( member.name, membertype, ' (optional)' if member.optional else '', - suffix) + suffix, desc) def texi_members(doc, what, base, variants, member_func): @@ -155,7 +163,7 @@ def texi_members(doc, what, base, variants, member_func): desc = 'One of ' + members_text + '\n' else: desc = 'Not documented\n' - items += member_func(section.member) + desc + items += member_func(section.member, desc, suffix='') if base: items += '@item The members of @code{%s}\n' % base.doc_type() if variants: @@ -165,7 +173,7 @@ def texi_members(doc, what, base, variants, member_func): if v.type.is_implicit(): assert not v.type.base and not v.type.variants for m in v.type.local_members: - items += member_func(m, when) + items += member_func(m, desc='', suffix=when) else: items += '@item The members of @code{%s}%s\n' % ( v.type.doc_type(), when) @@ -185,8 +193,7 @@ def texi_sections(doc, ifcond): body += texi_example(section.text) else: body += texi_format(section.text) - if ifcond: - body += '\n\n@b{If:} @code{%s}' % ", ".join(ifcond) + body += texi_if(ifcond, suffix='') return body diff --git a/tests/qapi-schema/doc-good.json b/tests/qapi-schema/doc-good.json index 984cd8ed06..1cd4935710 100644 --- a/tests/qapi-schema/doc-good.json +++ b/tests/qapi-schema/doc-good.json @@ -55,7 +55,9 @@ # # @two is undocumented ## -{ 'enum': 'Enum', 'data': [ 'one', 'two' ], 'if': 'defined(IFCOND)' } +{ 'enum': 'Enum', 'data': + [ { 'name': 'one', 'if': 'defined(IFONE)' }, 'two' ], + 'if': 'defined(IFCOND)' } ## # @Base: diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out index c2fc5c774a..53bd177f7d 100644 --- a/tests/qapi-schema/doc-good.out +++ b/tests/qapi-schema/doc-good.out @@ -11,6 +11,7 @@ enum QType module doc-good.json enum Enum member one + if ['defined(IFONE)'] member two if ['defined(IFCOND)'] object Base diff --git a/tests/qapi-schema/doc-good.texi b/tests/qapi-schema/doc-good.texi index e42eace474..405055b146 100644 --- a/tests/qapi-schema/doc-good.texi +++ b/tests/qapi-schema/doc-good.texi @@ -84,12 +84,12 @@ Examples: @table @asis @item @code{one} The @emph{one} @{and only@} +@*@b{If:} @code{defined(IFONE)} @item @code{two} Not documented @end table @code{two} is undocumented - @b{If:} @code{defined(IFCOND)} @end deftp From patchwork Thu Dec 13 18:43:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 1013075 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43G37K3G6Gz9s3Z for ; Fri, 14 Dec 2018 06:06:21 +1100 (AEDT) Received: from localhost ([::1]:54344 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXWJO-0007vJ-RZ for incoming@patchwork.ozlabs.org; Thu, 13 Dec 2018 14:06:18 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53376) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVy6-00061m-7V for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:19 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXVxv-0002yG-DI for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:12 -0500 Received: from mx1.redhat.com ([209.132.183.28]:36088) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gXVxr-0001hv-LY for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:05 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E3C3B30833A4 for ; Thu, 13 Dec 2018 18:43:49 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-56.ams2.redhat.com [10.36.116.56]) by smtp.corp.redhat.com (Postfix) with ESMTPS id A4E7361496; Thu, 13 Dec 2018 18:43:49 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id BDFF11132C2D; Thu, 13 Dec 2018 19:43:40 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2018 19:43:37 +0100 Message-Id: <20181213184340.24037-30-armbru@redhat.com> In-Reply-To: <20181213184340.24037-1-armbru@redhat.com> References: <20181213184340.24037-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.44]); Thu, 13 Dec 2018 18:43:49 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 29/32] qapi: add 'If:' condition to struct members documentation X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Signed-off-by: Marc-André Lureau Message-Id: <20181213123724.4866-20-marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster --- scripts/qapi/doc.py | 4 ++-- tests/qapi-schema/doc-good.json | 3 ++- tests/qapi-schema/doc-good.out | 1 + tests/qapi-schema/doc-good.texi | 1 + 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/scripts/qapi/doc.py b/scripts/qapi/doc.py index ab36b9dec6..b6f834b917 100755 --- a/scripts/qapi/doc.py +++ b/scripts/qapi/doc.py @@ -143,10 +143,10 @@ def texi_member(member, desc, suffix): """Format a table of members item for an object type member""" typ = member.type.doc_type() membertype = ': ' + typ if typ else '' - return '@item @code{%s%s}%s%s\n%s' % ( + return '@item @code{%s%s}%s%s\n%s%s' % ( member.name, membertype, ' (optional)' if member.optional else '', - suffix, desc) + suffix, desc, texi_if(member.ifcond, prefix='@*')) def texi_members(doc, what, base, variants, member_func): diff --git a/tests/qapi-schema/doc-good.json b/tests/qapi-schema/doc-good.json index 1cd4935710..28992fc615 100644 --- a/tests/qapi-schema/doc-good.json +++ b/tests/qapi-schema/doc-good.json @@ -72,7 +72,8 @@ # # Another paragraph (but no @var: line) ## -{ 'struct': 'Variant1', 'data': { 'var1': 'str' } } +{ 'struct': 'Variant1', + 'data': { 'var1': { 'type': 'str', 'if': 'defined(IFSTR)' } } } ## # @Variant2: diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out index 53bd177f7d..4ab55683ce 100644 --- a/tests/qapi-schema/doc-good.out +++ b/tests/qapi-schema/doc-good.out @@ -18,6 +18,7 @@ object Base member base1: Enum optional=False object Variant1 member var1: str optional=False + if ['defined(IFSTR)'] object Variant2 object Object base Base diff --git a/tests/qapi-schema/doc-good.texi b/tests/qapi-schema/doc-good.texi index 405055b146..f87f9faacb 100644 --- a/tests/qapi-schema/doc-good.texi +++ b/tests/qapi-schema/doc-good.texi @@ -119,6 +119,7 @@ Another paragraph (but no @code{var}: line) @table @asis @item @code{var1: string} Not documented +@*@b{If:} @code{defined(IFSTR)} @end table @end deftp From patchwork Thu Dec 13 18:43:38 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 1013060 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43G3022jZgz9s9G for ; Fri, 14 Dec 2018 06:00:00 +1100 (AEDT) Received: from localhost ([::1]:54306 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXWDG-0002Ww-0q for incoming@patchwork.ozlabs.org; Thu, 13 Dec 2018 13:59:58 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53274) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVxr-0005lE-OP for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:05 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXVxo-0002Sc-HH for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:03 -0500 Received: from mx1.redhat.com ([209.132.183.28]:33514) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gXVxm-0001iD-QL for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:59 -0500 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1F9DE88E4F for ; Thu, 13 Dec 2018 18:43:50 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-56.ams2.redhat.com [10.36.116.56]) by smtp.corp.redhat.com (Postfix) with ESMTPS id A7E285D756; Thu, 13 Dec 2018 18:43:49 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id C1B591132C2E; Thu, 13 Dec 2018 19:43:40 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2018 19:43:38 +0100 Message-Id: <20181213184340.24037-31-armbru@redhat.com> In-Reply-To: <20181213184340.24037-1-armbru@redhat.com> References: <20181213184340.24037-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Thu, 13 Dec 2018 18:43:50 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 30/32] qapi: add condition to variants documentation X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Signed-off-by: Marc-André Lureau Message-Id: <20181213123724.4866-21-marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster Signed-off-by: Markus Armbruster --- scripts/qapi/doc.py | 4 ++-- tests/qapi-schema/doc-good.json | 4 ++-- tests/qapi-schema/doc-good.out | 3 +++ tests/qapi-schema/doc-good.texi | 4 ++-- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/scripts/qapi/doc.py b/scripts/qapi/doc.py index b6f834b917..c03b690161 100755 --- a/scripts/qapi/doc.py +++ b/scripts/qapi/doc.py @@ -168,8 +168,8 @@ def texi_members(doc, what, base, variants, member_func): items += '@item The members of @code{%s}\n' % base.doc_type() if variants: for v in variants.variants: - when = ' when @code{%s} is @t{"%s"}' % ( - variants.tag_member.name, v.name) + when = ' when @code{%s} is @t{"%s"}%s' % ( + variants.tag_member.name, v.name, texi_if(v.ifcond, " (", ")")) if v.type.is_implicit(): assert not v.type.base and not v.type.variants for m in v.type.local_members: diff --git a/tests/qapi-schema/doc-good.json b/tests/qapi-schema/doc-good.json index 28992fc615..f7fb48af38 100644 --- a/tests/qapi-schema/doc-good.json +++ b/tests/qapi-schema/doc-good.json @@ -86,13 +86,13 @@ { 'union': 'Object', 'base': 'Base', 'discriminator': 'base1', - 'data': { 'one': 'Variant1', 'two': 'Variant2' } } + 'data': { 'one': 'Variant1', 'two': { 'type': 'Variant2', 'if': 'IFTWO' } } } ## # @SugaredUnion: ## { 'union': 'SugaredUnion', - 'data': { 'one': 'Variant1', 'two': 'Variant2' } } + 'data': { 'one': 'Variant1', 'two': { 'type': 'Variant2', 'if': 'IFTWO' } } } ## # == Another subsection diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out index 4ab55683ce..21bf345ff0 100644 --- a/tests/qapi-schema/doc-good.out +++ b/tests/qapi-schema/doc-good.out @@ -25,6 +25,7 @@ object Object tag base1 case one: Variant1 case two: Variant2 + if ['IFTWO'] object q_obj_Variant1-wrapper member data: Variant1 optional=False object q_obj_Variant2-wrapper @@ -32,11 +33,13 @@ object q_obj_Variant2-wrapper enum SugaredUnionKind member one member two + if ['IFTWO'] object SugaredUnion member type: SugaredUnionKind optional=False tag type case one: q_obj_Variant1-wrapper case two: q_obj_Variant2-wrapper + if ['IFTWO'] object q_obj_cmd-arg member arg1: int optional=False member arg2: str optional=True diff --git a/tests/qapi-schema/doc-good.texi b/tests/qapi-schema/doc-good.texi index f87f9faacb..2526abc6d9 100644 --- a/tests/qapi-schema/doc-good.texi +++ b/tests/qapi-schema/doc-good.texi @@ -142,7 +142,7 @@ Not documented @table @asis @item The members of @code{Base} @item The members of @code{Variant1} when @code{base1} is @t{"one"} -@item The members of @code{Variant2} when @code{base1} is @t{"two"} +@item The members of @code{Variant2} when @code{base1} is @t{"two"} (@b{If:} @code{IFTWO}) @end table @end deftp @@ -158,7 +158,7 @@ Not documented @item @code{type} One of @t{"one"}, @t{"two"} @item @code{data: Variant1} when @code{type} is @t{"one"} -@item @code{data: Variant2} when @code{type} is @t{"two"} +@item @code{data: Variant2} when @code{type} is @t{"two"} (@b{If:} @code{IFTWO}) @end table @end deftp From patchwork Thu Dec 13 18:43:39 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 1013057 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43G2wk6rsjz9s3Z for ; Fri, 14 Dec 2018 05:57:10 +1100 (AEDT) Received: from localhost ([::1]:54293 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXWAW-000803-BF for incoming@patchwork.ozlabs.org; Thu, 13 Dec 2018 13:57:08 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53191) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVxo-0005hX-Gh for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:02 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXVxl-0002Fd-4V for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:59 -0500 Received: from mx1.redhat.com ([209.132.183.28]:43118) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gXVxj-0001iB-JP for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:55 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 14388307CDE3 for ; Thu, 13 Dec 2018 18:43:50 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-56.ams2.redhat.com [10.36.116.56]) by smtp.corp.redhat.com (Postfix) with ESMTPS id D1CDE61B72; Thu, 13 Dec 2018 18:43:49 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id C57191132C31; Thu, 13 Dec 2018 19:43:40 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2018 19:43:39 +0100 Message-Id: <20181213184340.24037-32-armbru@redhat.com> In-Reply-To: <20181213184340.24037-1-armbru@redhat.com> References: <20181213184340.24037-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.49]); Thu, 13 Dec 2018 18:43:50 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 31/32] qapi: add more conditions to SPICE X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Now that member can be made conditional, let's make SPICE chardev conditional: * spiceport, spicevmc Before and after the patch for !CONFIG_SPICE, the error is the same ('spiceport' is not a valid char driver name). Signed-off-by: Marc-André Lureau Reviewed-by: Markus Armbruster Message-Id: <20181213123724.4866-22-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster --- qapi/char.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/qapi/char.json b/qapi/char.json index 24628331ec..77ed847972 100644 --- a/qapi/char.json +++ b/qapi/char.json @@ -332,8 +332,8 @@ ## { 'struct': 'ChardevSpiceChannel', 'data': { 'type': 'str' }, - 'base': 'ChardevCommon' } -# TODO: 'if': 'defined(CONFIG_SPICE)' + 'base': 'ChardevCommon', + 'if': 'defined(CONFIG_SPICE)' } ## # @ChardevSpicePort: @@ -346,8 +346,8 @@ ## { 'struct': 'ChardevSpicePort', 'data': { 'fqdn': 'str' }, - 'base': 'ChardevCommon' } -# TODO: 'if': 'defined(CONFIG_SPICE)' + 'base': 'ChardevCommon', + 'if': 'defined(CONFIG_SPICE)' } ## # @ChardevVC: @@ -404,10 +404,10 @@ 'testdev': 'ChardevCommon', 'stdio': 'ChardevStdio', 'console': 'ChardevCommon', - 'spicevmc': 'ChardevSpiceChannel', -# TODO: { 'type': 'ChardevSpiceChannel', 'if': 'defined(CONFIG_SPICE)' }, - 'spiceport': 'ChardevSpicePort', -# TODO: { 'type': 'ChardevSpicePort', 'if': 'defined(CONFIG_SPICE)' }, + 'spicevmc': { 'type': 'ChardevSpiceChannel', + 'if': 'defined(CONFIG_SPICE)' }, + 'spiceport': { 'type': 'ChardevSpicePort', + 'if': 'defined(CONFIG_SPICE)' }, 'vc': 'ChardevVC', 'ringbuf': 'ChardevRingbuf', # next one is just for compatibility From patchwork Thu Dec 13 18:43:40 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 1013049 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43G2ny30jqz9s3Z for ; Fri, 14 Dec 2018 05:51:18 +1100 (AEDT) Received: from localhost ([::1]:54264 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXW4p-0002TU-9n for incoming@patchwork.ozlabs.org; Thu, 13 Dec 2018 13:51:15 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53266) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXVxr-0005l8-KX for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:05 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXVxn-0002Rm-TP for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:44:03 -0500 Received: from mx1.redhat.com ([209.132.183.28]:46396) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gXVxl-0001ie-Vh for qemu-devel@nongnu.org; Thu, 13 Dec 2018 13:43:58 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 4434C4E93D for ; Thu, 13 Dec 2018 18:43:50 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-116-56.ams2.redhat.com [10.36.116.56]) by smtp.corp.redhat.com (Postfix) with ESMTPS id DA36061B81; Thu, 13 Dec 2018 18:43:49 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id C920D1132C35; Thu, 13 Dec 2018 19:43:40 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2018 19:43:40 +0100 Message-Id: <20181213184340.24037-33-armbru@redhat.com> In-Reply-To: <20181213184340.24037-1-armbru@redhat.com> References: <20181213184340.24037-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Thu, 13 Dec 2018 18:43:50 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 32/32] qapi: add conditions to REPLICATION type/commands on the schema X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Marc-André Lureau Add #if defined(CONFIG_REPLICATION) in generated code, and adjust the code accordingly. Made conditional: * xen-set-replication, query-xen-replication-status, xen-colo-do-checkpoint Before the patch, we first register the commands unconditionally in generated code (requires a stub), then conditionally unregister in qmp_unregister_commands_hack(). Afterwards, we register only when CONFIG_REPLICATION. The command fails exactly the same, with CommandNotFound. Improvement, because now query-qmp-schema is accurate, and we're one step closer to killing qmp_unregister_commands_hack(). * enum BlockdevDriver value "replication" in command blockdev-add * BlockdevOptions variant @replication and related structures. Signed-off-by: Marc-André Lureau Reviewed-by: Markus Armbruster Message-Id: <20181213123724.4866-23-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster --- migration/colo.c | 16 ++++------------ monitor.c | 5 ----- qapi/block-core.json | 13 +++++++++---- qapi/migration.json | 12 ++++++++---- 4 files changed, 21 insertions(+), 25 deletions(-) diff --git a/migration/colo.c b/migration/colo.c index fcff04c78c..398b239d1c 100644 --- a/migration/colo.c +++ b/migration/colo.c @@ -24,7 +24,9 @@ #include "trace.h" #include "qemu/error-report.h" #include "migration/failover.h" +#ifdef CONFIG_REPLICATION #include "replication.h" +#endif #include "net/colo-compare.h" #include "net/colo.h" #include "block/block.h" @@ -201,11 +203,11 @@ void colo_do_failover(MigrationState *s) } } +#ifdef CONFIG_REPLICATION void qmp_xen_set_replication(bool enable, bool primary, bool has_failover, bool failover, Error **errp) { -#ifdef CONFIG_REPLICATION ReplicationMode mode = primary ? REPLICATION_MODE_PRIMARY : REPLICATION_MODE_SECONDARY; @@ -224,14 +226,10 @@ void qmp_xen_set_replication(bool enable, bool primary, } replication_stop_all(failover, failover ? NULL : errp); } -#else - abort(); -#endif } ReplicationStatus *qmp_query_xen_replication_status(Error **errp) { -#ifdef CONFIG_REPLICATION Error *err = NULL; ReplicationStatus *s = g_new0(ReplicationStatus, 1); @@ -246,19 +244,13 @@ ReplicationStatus *qmp_query_xen_replication_status(Error **errp) error_free(err); return s; -#else - abort(); -#endif } void qmp_xen_colo_do_checkpoint(Error **errp) { -#ifdef CONFIG_REPLICATION replication_do_checkpoint_all(errp); -#else - abort(); -#endif } +#endif COLOStatus *qmp_query_colo_status(Error **errp) { diff --git a/monitor.c b/monitor.c index cf9cece965..7848a3cb0d 100644 --- a/monitor.c +++ b/monitor.c @@ -1147,11 +1147,6 @@ static void qmp_query_qmp_schema(QDict *qdict, QObject **ret_data, */ static void qmp_unregister_commands_hack(void) { -#ifndef CONFIG_REPLICATION - qmp_unregister_command(&qmp_commands, "xen-set-replication"); - qmp_unregister_command(&qmp_commands, "query-xen-replication-status"); - qmp_unregister_command(&qmp_commands, "xen-colo-do-checkpoint"); -#endif #ifndef TARGET_I386 qmp_unregister_command(&qmp_commands, "rtc-reset-reinjection"); qmp_unregister_command(&qmp_commands, "query-sev"); diff --git a/qapi/block-core.json b/qapi/block-core.json index 92e0205d91..762000f31f 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -2623,7 +2623,9 @@ 'copy-on-read', 'dmg', 'file', 'ftp', 'ftps', 'gluster', 'host_cdrom', 'host_device', 'http', 'https', 'iscsi', 'luks', 'nbd', 'nfs', 'null-aio', 'null-co', 'nvme', 'parallels', 'qcow', - 'qcow2', 'qed', 'quorum', 'raw', 'rbd', 'replication', 'sheepdog', + 'qcow2', 'qed', 'quorum', 'raw', 'rbd', + { 'name': 'replication', 'if': 'defined(CONFIG_REPLICATION)' }, + 'sheepdog', 'ssh', 'throttle', 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat', 'vxhs' ] } ## @@ -3380,7 +3382,8 @@ # # Since: 2.9 ## -{ 'enum' : 'ReplicationMode', 'data' : [ 'primary', 'secondary' ] } +{ 'enum' : 'ReplicationMode', 'data' : [ 'primary', 'secondary' ], + 'if': 'defined(CONFIG_REPLICATION)' } ## # @BlockdevOptionsReplication: @@ -3398,7 +3401,8 @@ { 'struct': 'BlockdevOptionsReplication', 'base': 'BlockdevOptionsGenericFormat', 'data': { 'mode': 'ReplicationMode', - '*top-id': 'str' } } + '*top-id': 'str' }, + 'if': 'defined(CONFIG_REPLICATION)' } ## # @NFSTransport: @@ -3714,7 +3718,8 @@ 'quorum': 'BlockdevOptionsQuorum', 'raw': 'BlockdevOptionsRaw', 'rbd': 'BlockdevOptionsRbd', - 'replication':'BlockdevOptionsReplication', + 'replication': { 'type': 'BlockdevOptionsReplication', + 'if': 'defined(CONFIG_REPLICATION)' }, 'sheepdog': 'BlockdevOptionsSheepdog', 'ssh': 'BlockdevOptionsSsh', 'throttle': 'BlockdevOptionsThrottle', diff --git a/qapi/migration.json b/qapi/migration.json index 5fd33316a0..31b589ec26 100644 --- a/qapi/migration.json +++ b/qapi/migration.json @@ -1257,7 +1257,8 @@ # Since: 2.9 ## { 'command': 'xen-set-replication', - 'data': { 'enable': 'bool', 'primary': 'bool', '*failover' : 'bool' } } + 'data': { 'enable': 'bool', 'primary': 'bool', '*failover' : 'bool' }, + 'if': 'defined(CONFIG_REPLICATION)' } ## # @ReplicationStatus: @@ -1272,7 +1273,8 @@ # Since: 2.9 ## { 'struct': 'ReplicationStatus', - 'data': { 'error': 'bool', '*desc': 'str' } } + 'data': { 'error': 'bool', '*desc': 'str' }, + 'if': 'defined(CONFIG_REPLICATION)' } ## # @query-xen-replication-status: @@ -1289,7 +1291,8 @@ # Since: 2.9 ## { 'command': 'query-xen-replication-status', - 'returns': 'ReplicationStatus' } + 'returns': 'ReplicationStatus', + 'if': 'defined(CONFIG_REPLICATION)' } ## # @xen-colo-do-checkpoint: @@ -1305,7 +1308,8 @@ # # Since: 2.9 ## -{ 'command': 'xen-colo-do-checkpoint' } +{ 'command': 'xen-colo-do-checkpoint', + 'if': 'defined(CONFIG_REPLICATION)' } ## # @COLOStatus: