From patchwork Sat Feb 6 18:59:13 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: john cooper X-Patchwork-Id: 44723 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 BF10AB7D30 for ; Sun, 7 Feb 2010 06:16:14 +1100 (EST) Received: from localhost ([127.0.0.1]:47840 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Ndq1Q-0005QQ-Pm for incoming@patchwork.ozlabs.org; Sat, 06 Feb 2010 14:08:48 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Ndq0K-0005QL-1p for qemu-devel@nongnu.org; Sat, 06 Feb 2010 14:07:40 -0500 Received: from [199.232.76.173] (port=36327 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Ndq0J-0005QD-Kz for qemu-devel@nongnu.org; Sat, 06 Feb 2010 14:07:39 -0500 Received: from Debian-exim by monty-python.gnu.org with spam-scanned (Exim 4.60) (envelope-from ) id 1Ndq0G-0005Fp-Af for qemu-devel@nongnu.org; Sat, 06 Feb 2010 14:07:39 -0500 Received: from mx1.redhat.com ([209.132.183.28]:37556) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1Ndq0F-0005FV-QZ for qemu-devel@nongnu.org; Sat, 06 Feb 2010 14:07:36 -0500 Received: from int-mx03.intmail.prod.int.phx2.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o16J7Vlp018704 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Sat, 6 Feb 2010 14:07:31 -0500 Received: from anvil.naka.net (pilototp-int.redhat.com [10.11.232.41]) by int-mx03.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o16J7MCW017765; Sat, 6 Feb 2010 14:07:24 -0500 Message-ID: <4B6DBC01.4060307@redhat.com> Date: Sat, 06 Feb 2010 13:59:13 -0500 From: john cooper User-Agent: Thunderbird 2.0.0.9 (X11/20071115) MIME-Version: 1.0 To: KVM list , qemu-devel@nongnu.org References: <4B672535.5050303@redhat.com> In-Reply-To: <4B672535.5050303@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.16 X-detected-operating-system: by monty-python.gnu.org: Genre and OS details not recognized. Cc: john.cooper@redhat.com, "Przywara, Andre" , Mark McLoughlin Subject: [Qemu-devel] [PATCH] Add assignment operation to config file parser.. 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 patch reworks support for both assignment and append in the config file parser. It was motivated by comments received on the cpu model config file format. Commit dc9ca4ba27be4fe6a0284061b8f056c4364fb0d9 changed the behavior of "=" from assign to append. This patch preserves the ability to append to an option (however now via "+="), reverts "=" to its previous behavior, and allows both to interoperate. Signed-off-by: john cooper diff --git a/qemu-config.c b/qemu-config.c index 246fae6..4e53250 100644 --- a/qemu-config.c +++ b/qemu-config.c @@ -429,6 +429,7 @@ int qemu_config_parse(FILE *fp) char line[1024], group[64], id[64], arg[64], value[1024]; QemuOptsList *list = NULL; QemuOpts *opts = NULL; + char append; while (fgets(line, sizeof(line), fp) != NULL) { if (line[0] == '\n') { @@ -455,13 +456,16 @@ int qemu_config_parse(FILE *fp) opts = qemu_opts_create(list, NULL, 0); continue; } - if (sscanf(line, " %63s = \"%1023[^\"]\"", arg, value) == 2) { - /* arg = value */ + append = 0; + if (sscanf(line, " %63s = \"%1023[^\"]\"", arg, value) == 2 || + (sscanf(line, " %63s += \"%1023[^\"]\"", arg, value) == 2 ? + append = 1 : 0)) { + /* arg = value, arg += value */ if (opts == NULL) { fprintf(stderr, "no group defined\n"); return -1; } - if (qemu_opt_set(opts, arg, value) != 0) { + if (_qemu_opt_set(opts, arg, value, append) != 0) { fprintf(stderr, "failed to set \"%s\" for %s\n", arg, group); return -1; diff --git a/qemu-option.c b/qemu-option.c index a52a4c4..7c0faed 100644 --- a/qemu-option.c +++ b/qemu-option.c @@ -562,7 +562,11 @@ static void qemu_opt_del(QemuOpt *opt) qemu_free(opt); } -int qemu_opt_set(QemuOpts *opts, const char *name, const char *value) +/* add option *name,*value to group *opts. if append add to tail of option + * list, else set as sole element (overwrite any existing entries of *name). + */ +int _qemu_opt_set(QemuOpts *opts, const char *name, const char *value, + char append) { QemuOpt *opt; QemuOptDesc *desc = opts->list->desc; @@ -582,13 +586,27 @@ int qemu_opt_set(QemuOpts *opts, const char *name, const char *value) return -1; } } - - opt = qemu_mallocz(sizeof(*opt)); - opt->name = qemu_strdup(name); - opt->opts = opts; - QTAILQ_INSERT_TAIL(&opts->head, opt, next); - if (desc[i].name != NULL) { - opt->desc = desc+i; + if (append || !(opt = qemu_opt_find(opts, name))) { + opt = qemu_mallocz(sizeof(*opt)); + opt->name = qemu_strdup(name); + opt->opts = opts; + QTAILQ_INSERT_TAIL(&opts->head, opt, next); + if (desc[i].name != NULL) { + opt->desc = desc+i; + } + } else if (!append) { + QemuOpt *p, *next; + + /* assign to reclaimed *opt, remove all other *name defs */ + QTAILQ_FOREACH_SAFE(p, &opts->head, next, next) { + if (p != opt && !strcmp(name, p->name)) { + qemu_free((char *)p->str); + QTAILQ_REMOVE(&opts->head, p, next); + qemu_free((char *)p); + } + } + qemu_free((char *)opt->str); + opt->str = NULL; } if (value) { opt->str = qemu_strdup(value); diff --git a/qemu-option.h b/qemu-option.h index 666b666..2385b1a 100644 --- a/qemu-option.h +++ b/qemu-option.h @@ -104,7 +104,14 @@ 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_set(QemuOpts *opts, const char *name, const char *value); +int _qemu_opt_set(QemuOpts *opts, const char *name, const char *value, + char append); +static inline int qemu_opt_set(QemuOpts *opts, const char *name, + const char *value) +{ + return (_qemu_opt_set(opts, name, value, 0)); +} + 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, int abort_on_failure);