From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38635) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Uzohr-0007fA-RS for qemu-devel@nongnu.org; Thu, 18 Jul 2013 09:57:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Uzoho-0006fh-PO for qemu-devel@nongnu.org; Thu, 18 Jul 2013 09:57:19 -0400 Received: from mx1.redhat.com ([209.132.183.28]:39040) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Uzoho-0006fY-HK for qemu-devel@nongnu.org; Thu, 18 Jul 2013 09:57:16 -0400 From: Laszlo Ersek Date: Thu, 18 Jul 2013 15:59:20 +0200 Message-Id: <1374155964-11278-3-git-send-email-lersek@redhat.com> In-Reply-To: <1374155964-11278-1-git-send-email-lersek@redhat.com> References: <1374155964-11278-1-git-send-email-lersek@redhat.com> Subject: [Qemu-devel] [RFC 2/6] OptsVisitor: introduce list modes for interval flattening List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org, pbonzini@redhat.com, gaowanlong@cn.fujitsu.com The new modes are equal-rank, exclusive sub-modes 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 | 44 ++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 42 insertions(+), 2 deletions(-) diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c index ab9a602..e8e317f 100644 --- a/qapi/opts-visitor.c +++ b/qapi/opts-visitor.c @@ -22,7 +22,9 @@ 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 */ + LM_SIGNED_INTERVAL, /* flattening an interval with signed bounds */ + LM_UNSIGNED_INTERVAL /* flattening an interval with unsigned bounds */ }; typedef enum ListMode ListMode; @@ -47,6 +49,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 +196,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 +238,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 +333,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 +363,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; -- 1.7.1