From patchwork Mon Jun 7 14:42:17 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= X-Patchwork-Id: 54867 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 16DB5B7D1C for ; Tue, 8 Jun 2010 00:58:00 +1000 (EST) Received: from localhost ([127.0.0.1]:34781 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OLdm1-0006Bj-81 for incoming@patchwork.ozlabs.org; Mon, 07 Jun 2010 10:57:57 -0400 Received: from [140.186.70.92] (port=56214 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OLdXs-0005qM-6w for qemu-devel@nongnu.org; Mon, 07 Jun 2010 10:43:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OLdXd-00054z-QB for qemu-devel@nongnu.org; Mon, 07 Jun 2010 10:43:19 -0400 Received: from mx1.redhat.com ([209.132.183.28]:38313) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OLdXd-00054n-Fl for qemu-devel@nongnu.org; Mon, 07 Jun 2010 10:43:05 -0400 Received: from int-mx05.intmail.prod.int.phx2.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.18]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o57Eh4TI013292 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 7 Jun 2010 10:43:04 -0400 Received: from localhost.localdomain (dhcp-1-192.lcy.redhat.com [10.32.224.192]) by int-mx05.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o57EgrCV031909; Mon, 7 Jun 2010 10:43:02 -0400 From: "Daniel P. Berrange" To: qemu-devel@nongnu.org Date: Mon, 7 Jun 2010 15:42:17 +0100 Message-Id: <1275921752-29420-5-git-send-email-berrange@redhat.com> In-Reply-To: <1275921752-29420-1-git-send-email-berrange@redhat.com> References: <1275921752-29420-1-git-send-email-berrange@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.18 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. Cc: Subject: [Qemu-devel] [PATCH 04/19] Add support for a option parameter as an enum X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This adds a new option parameter QEMU_OPT_ENUM. The user provides the value in its string representation. The parser validates this and converts it to integer representation for internal use. If the user supplies an invalid value it will report the precise allowed list of values. Signed-off-by: Daniel P. Berrange --- qemu-option.c | 31 +++++++++++++++++++++++++++++++ qemu-option.h | 10 ++++++++++ 2 files changed, 41 insertions(+), 0 deletions(-) diff --git a/qemu-option.c b/qemu-option.c index acd74f9..bb9cc43 100644 --- a/qemu-option.c +++ b/qemu-option.c @@ -238,6 +238,24 @@ static int parse_option_size(const char *name, const char *value, uint64_t *ret) return 0; } +static int parse_option_enum(const char *name, const char *value, int *ret, const QemuOptDesc *desc) +{ + if (!value) { + qerror_report(QERR_INVALID_PARAMETER_VALUE, name, "a enumerated string"); + return -1; + } + + *ret = (desc->validate.optEnum.from_string)(value); + if (*ret < 0) { + char *valid = (desc->validate.optEnum.to_string_list)(); + qerror_report(QERR_INVALID_PARAMETER_VALUE, name, valid); + qemu_free(valid); + return -1; + } + return 0; +} + + /* * Sets the value of a parameter in a given option list. The parsing of the * value depends on the type of option: @@ -516,6 +534,7 @@ struct QemuOpt { union { int boolean; uint64_t uint; + int enumVal; } value; QemuOpts *opts; @@ -578,6 +597,16 @@ uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval) return opt->value.uint; } +int qemu_opt_get_enum(QemuOpts *opts, const char *name, int defval) +{ + QemuOpt *opt = qemu_opt_find(opts, name); + + if (opt == NULL) + return defval; + assert(opt->desc && opt->desc->type == QEMU_OPT_ENUM); + return opt->value.enumVal; +} + static int qemu_opt_parse(QemuOpt *opt) { if (opt->desc == NULL) @@ -592,6 +621,8 @@ static int qemu_opt_parse(QemuOpt *opt) return parse_option_number(opt->name, opt->str, &opt->value.uint); case QEMU_OPT_SIZE: return parse_option_size(opt->name, opt->str, &opt->value.uint); + case QEMU_OPT_ENUM: + return parse_option_enum(opt->name, opt->str, &opt->value.enumVal, opt->desc); default: abort(); } diff --git a/qemu-option.h b/qemu-option.h index 4823219..3540a9b 100644 --- a/qemu-option.h +++ b/qemu-option.h @@ -89,12 +89,21 @@ enum QemuOptType { QEMU_OPT_BOOL, /* on/off */ QEMU_OPT_NUMBER, /* simple number */ QEMU_OPT_SIZE, /* size, accepts (K)ilo, (M)ega, (G)iga, (T)era postfix */ + QEMU_OPT_ENUM, /* int, from user string validated against an enum */ }; typedef struct QemuOptDesc { const char *name; enum QemuOptType type; const char *help; + union { + struct { + int (*from_string)(const char *); + const char *(*to_string)(int); + char *(*to_string_list)(void); + int last; + } optEnum; + } validate; } QemuOptDesc; struct QemuOptsList { @@ -108,6 +117,7 @@ const char *qemu_opt_get(QemuOpts *opts, const char *name); int qemu_opt_get_bool(QemuOpts *opts, const char *name, int defval); uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval); uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval); +int qemu_opt_get_enum(QemuOpts *opts, const char *name, int defval); int qemu_opt_set(QemuOpts *opts, const char *name, const char *value); typedef int (*qemu_opt_loopfunc)(const char *name, const char *value, void *opaque); int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque,