From patchwork Mon Aug 19 22:35:34 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laszlo Ersek X-Patchwork-Id: 268320 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id B4F502C0132 for ; Tue, 20 Aug 2013 08:51:24 +1000 (EST) Received: from localhost ([::1]:45132 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VBY31-0005X8-LE for incoming@patchwork.ozlabs.org; Mon, 19 Aug 2013 18:35:39 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58737) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VBY0u-0002eU-A7 for qemu-devel@nongnu.org; Mon, 19 Aug 2013 18:33:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VBY0i-0008OJ-6i for qemu-devel@nongnu.org; Mon, 19 Aug 2013 18:33:28 -0400 Received: from mx1.redhat.com ([209.132.183.28]:27814) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VBY0h-0008OC-Uh for qemu-devel@nongnu.org; Mon, 19 Aug 2013 18:33:16 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r7JMXFjN015345 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 19 Aug 2013 18:33:15 -0400 Received: from lacos-laptop.usersys.redhat.com (vpn1-5-138.ams2.redhat.com [10.36.5.138]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id r7JMXBpi017933; Mon, 19 Aug 2013 18:33:14 -0400 From: Laszlo Ersek To: lcapitulino@redhat.com, qemu-devel@nongnu.org Date: Tue, 20 Aug 2013 00:35:34 +0200 Message-Id: <1376951740-23559-3-git-send-email-lersek@redhat.com> In-Reply-To: <1376951740-23559-1-git-send-email-lersek@redhat.com> References: <1376951740-23559-1-git-send-email-lersek@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v2 2/8] OptsVisitor: introduce list modes for interval flattening X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org The new modes are equal-rank, exclusive alternatives of LM_IN_PROGRESS. Teach opts_next_list(), opts_type_int() and opts_type_uint64() to handle them. Also enumerate explicitly what functions are valid to call in what modes: - opts_next_list() is valid to call while flattening a range, - opts_end_list(): ditto, - lookup_scalar() is invalid to call during flattening; generated qapi traversal code must continue asking for the same kind of signed/unsigned list element until the interval is fully flattened, - processed(): ditto. List mode restrictions are always formulated in positive / inclusive sense. The restrictions for lookup_scalar() and processed() are automatically satisfied by current qapi traversals if the schema to build is compatible with OptsVisitor. The new list modes are not entered yet. Signed-off-by: Laszlo Ersek --- qapi/opts-visitor.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 65 insertions(+), 2 deletions(-) diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c index 29fd1ab..c2a57bd 100644 --- a/qapi/opts-visitor.c +++ b/qapi/opts-visitor.c @@ -22,7 +22,32 @@ enum ListMode { LM_NONE, /* not traversing a list of repeated options */ LM_STARTED, /* opts_start_list() succeeded */ - LM_IN_PROGRESS /* opts_next_list() has been called */ + + LM_IN_PROGRESS, /* opts_next_list() has been called. + * + * Generating the next list link will consume the most + * recently parsed QemuOpt instance of the repeated + * option. + * + * Parsing a value into the list link will examine the + * next QemuOpt instance of the repeated option, and + * possibly enter LM_SIGNED_INTERVAL or + * LM_UNSIGNED_INTERVAL. + */ + + LM_SIGNED_INTERVAL, /* opts_next_list() has been called. + * + * Generating the next list link will consume the most + * recently stored element from the signed interval, + * parsed from the most recent QemuOpt instance of the + * repeated option. This may consume QemuOpt itself + * and return to LM_IN_PROGRESS. + * + * Parsing a value into the list link will store the + * next element of the signed interval. + */ + + LM_UNSIGNED_INTERVAL /* Same as above, only for an unsigned interval. */ }; typedef enum ListMode ListMode; @@ -47,6 +72,15 @@ struct OptsVisitor ListMode list_mode; GQueue *repeated_opts; + /* When parsing a list of repeating options as integers, values of the form + * "a-b", representing a closed interval, are allowed. Elements in the + * range are generated individually. + */ + union { + int64_t s; + uint64_t u; + } range_next, range_limit; + /* If "opts_root->id" is set, reinstantiate it as a fake QemuOpt for * uniformity. Only its "name" and "str" fields are set. "fake_id_opt" does * not survive or escape the OptsVisitor object. @@ -185,6 +219,22 @@ opts_next_list(Visitor *v, GenericList **list, Error **errp) link = list; break; + case LM_SIGNED_INTERVAL: + case LM_UNSIGNED_INTERVAL: + link = &(*list)->next; + + if (ov->list_mode == LM_SIGNED_INTERVAL) { + if (ov->range_next.s < ov->range_limit.s) { + ++ov->range_next.s; + break; + } + } else if (ov->range_next.u < ov->range_limit.u) { + ++ov->range_next.u; + break; + } + ov->list_mode = LM_IN_PROGRESS; + /* range has been completed, fall through in order to pop option */ + case LM_IN_PROGRESS: { const QemuOpt *opt; @@ -211,7 +261,10 @@ opts_end_list(Visitor *v, Error **errp) { OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v); - assert(ov->list_mode == LM_STARTED || ov->list_mode == LM_IN_PROGRESS); + assert(ov->list_mode == LM_STARTED || + ov->list_mode == LM_IN_PROGRESS || + ov->list_mode == LM_SIGNED_INTERVAL || + ov->list_mode == LM_UNSIGNED_INTERVAL); ov->repeated_opts = NULL; ov->list_mode = LM_NONE; } @@ -303,6 +356,11 @@ opts_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp) long long val; char *endptr; + if (ov->list_mode == LM_SIGNED_INTERVAL) { + *obj = ov->range_next.s; + return; + } + opt = lookup_scalar(ov, name, errp); if (!opt) { return; @@ -328,6 +386,11 @@ opts_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp) const QemuOpt *opt; const char *str; + if (ov->list_mode == LM_UNSIGNED_INTERVAL) { + *obj = ov->range_next.u; + return; + } + opt = lookup_scalar(ov, name, errp); if (!opt) { return;