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: 77554 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o16J7i1Z006299 for ; Sat, 6 Feb 2010 19:07:44 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932592Ab0BFTHh (ORCPT ); Sat, 6 Feb 2010 14:07:37 -0500 Received: from mx1.redhat.com ([209.132.183.28]:15846 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932464Ab0BFTHg (ORCPT ); Sat, 6 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 CC: "Przywara, Andre" , Anthony Liguori , Mark McLoughlin , john.cooper@redhat.com Subject: [PATCH] Add assignment operation to config file parser.. References: <4B672535.5050303@redhat.com> In-Reply-To: <4B672535.5050303@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.16 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Sat, 06 Feb 2010 19:07:44 +0000 (UTC) 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);