From nobody Mon Feb 9 07:23:38 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547148057393786.4235717910785; Thu, 10 Jan 2019 11:20:57 -0800 (PST) Received: from localhost ([127.0.0.1]:60054 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghfsk-00066d-Q0 for importer@patchew.org; Thu, 10 Jan 2019 14:20:46 -0500 Received: from eggs.gnu.org ([209.51.188.92]:56474) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghfrB-00050C-5R for qemu-devel@nongnu.org; Thu, 10 Jan 2019 14:19:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ghfrA-0008Pg-1t for qemu-devel@nongnu.org; Thu, 10 Jan 2019 14:19:09 -0500 Received: from mx1.redhat.com ([209.132.183.28]:60766) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ghfr7-0008MQ-BV; Thu, 10 Jan 2019 14:19:05 -0500 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6F3E08E664; Thu, 10 Jan 2019 19:19:04 +0000 (UTC) Received: from blue.redhat.com (ovpn-116-216.phx2.redhat.com [10.3.116.216]) by smtp.corp.redhat.com (Postfix) with ESMTP id E470760C67; Thu, 10 Jan 2019 19:19:03 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Thu, 10 Jan 2019 13:18:55 -0600 Message-Id: <20190110191901.5082-2-eblake@redhat.com> In-Reply-To: <20190110191901.5082-1-eblake@redhat.com> References: <20190110191901.5082-1-eblake@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Thu, 10 Jan 2019 19:19:04 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v3 1/6] qemu-option: Allow integer defaults X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, lbloch@janustech.com, armbru@redhat.com, qemu-block@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Set the framework up for declaring integer options with an integer default, instead of our current insane approach of requiring the default value to be given as a string (which then has to be reparsed at every use that wants a number). git grep '[^.]def_value_str' says that we have done a good job of NOT abusing the internal field outside of the implementation in qemu-option.c; therefore, it is not too hard to audit that all code can either handle the new integer defaults correctly or abort because a caller violated constraints. Sadly, we DO have a constraint that qemu_opt_get() should not be called on an option that has an integer type, because we have no where to stash a cached const char * result; but callers that want an integer should be using qemu_opt_get_number() and friends anyways. Signed-off-by: Eric Blake --- include/qemu/option.h | 12 ++++++++ util/qemu-option.c | 69 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 72 insertions(+), 9 deletions(-) diff --git a/include/qemu/option.h b/include/qemu/option.h index 844587cab39..46b80d5a6e1 100644 --- a/include/qemu/option.h +++ b/include/qemu/option.h @@ -46,6 +46,18 @@ typedef struct QemuOptDesc { const char *name; enum QemuOptType type; const char *help; + /* + * For QEMU_OPT_STRING: Leave def_value_int 0, and set def_value_str + * to a default value or leave NULL for no default. + * + * For other types: Initialize at most non-zero def_value_int or a + * parseable def_value_str for a default (must use a string for an + * explicit default of 0, although an implicit default generally + * works). If setting def_value_int, calling qemu_opt_get() on + * that option will abort(); instead, call qemu_opt_get_del() or a + * typed getter. + */ + uint64_t def_value_int; const char *def_value_str; } QemuOptDesc; diff --git a/util/qemu-option.c b/util/qemu-option.c index de42e2a406a..06c4e8102a8 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -321,7 +321,8 @@ const char *qemu_opt_get(QemuOpts *opts, const char *na= me) opt =3D qemu_opt_find(opts, name); if (!opt) { const QemuOptDesc *desc =3D find_desc_by_name(opts->list->desc, na= me); - if (desc && desc->def_value_str) { + if (desc) { + assert(!desc->def_value_int); return desc->def_value_str; } } @@ -364,8 +365,22 @@ char *qemu_opt_get_del(QemuOpts *opts, const char *nam= e) opt =3D qemu_opt_find(opts, name); if (!opt) { desc =3D find_desc_by_name(opts->list->desc, name); - if (desc && desc->def_value_str) { - str =3D g_strdup(desc->def_value_str); + if (desc) { + if (desc->def_value_str) { + str =3D g_strdup(desc->def_value_str); + } else if (desc->def_value_int) { + switch (desc->type) { + case QEMU_OPT_BOOL: + str =3D g_strdup("on"); + break; + case QEMU_OPT_NUMBER: + case QEMU_OPT_SIZE: + str =3D g_strdup_printf("%" PRId64, desc->def_value_in= t); + break; + default: + abort(); + } + } } return str; } @@ -400,8 +415,15 @@ static bool qemu_opt_get_bool_helper(QemuOpts *opts, c= onst char *name, opt =3D qemu_opt_find(opts, name); if (opt =3D=3D NULL) { const QemuOptDesc *desc =3D find_desc_by_name(opts->list->desc, na= me); - if (desc && desc->def_value_str) { - parse_option_bool(name, desc->def_value_str, &ret, &error_abor= t); + if (desc) { + if (desc->def_value_int) { + assert(desc->type !=3D QEMU_OPT_STRING); + return true; + } + if (desc->def_value_str) { + parse_option_bool(name, desc->def_value_str, &ret, + &error_abort); + } } return ret; } @@ -436,8 +458,15 @@ static uint64_t qemu_opt_get_number_helper(QemuOpts *o= pts, const char *name, opt =3D qemu_opt_find(opts, name); if (opt =3D=3D NULL) { const QemuOptDesc *desc =3D find_desc_by_name(opts->list->desc, na= me); - if (desc && desc->def_value_str) { - parse_option_number(name, desc->def_value_str, &ret, &error_ab= ort); + if (desc) { + if (desc->def_value_int) { + assert(desc->type !=3D QEMU_OPT_STRING); + return desc->def_value_int; + } + if (desc->def_value_str) { + parse_option_number(name, desc->def_value_str, &ret, + &error_abort); + } } return ret; } @@ -473,8 +502,15 @@ static uint64_t qemu_opt_get_size_helper(QemuOpts *opt= s, const char *name, opt =3D qemu_opt_find(opts, name); if (opt =3D=3D NULL) { const QemuOptDesc *desc =3D find_desc_by_name(opts->list->desc, na= me); - if (desc && desc->def_value_str) { - parse_option_size(name, desc->def_value_str, &ret, &error_abor= t); + if (desc) { + if (desc->def_value_int) { + assert(desc->type !=3D QEMU_OPT_STRING); + return desc->def_value_int; + } + if (desc->def_value_str) { + parse_option_size(name, desc->def_value_str, &ret, + &error_abort); + } } return ret; } @@ -787,9 +823,23 @@ void qemu_opts_print(QemuOpts *opts, const char *separ= ator) } for (; desc && desc->name; desc++) { const char *value; + char *tmp =3D NULL; opt =3D qemu_opt_find(opts, desc->name); value =3D opt ? opt->str : desc->def_value_str; + if (!value && desc->def_value_int) { + switch (desc->type) { + case QEMU_OPT_BOOL: + value =3D tmp =3D g_strdup("on"); + break; + case QEMU_OPT_NUMBER: + case QEMU_OPT_SIZE: + value =3D tmp =3D g_strdup_printf("%" PRId64, desc->def_va= lue_int); + break; + default: + abort(); + } + } if (!value) { continue; } @@ -803,6 +853,7 @@ void qemu_opts_print(QemuOpts *opts, const char *separa= tor) printf("%s%s=3D%s", sep, desc->name, value); } sep =3D separator; + g_free(tmp); } } --=20 2.20.1