]> git.proxmox.com Git - mirror_qemu.git/commitdiff
qapi: Change data type of the FOO_lookup generated for enum FOO
authorMarc-André Lureau <marcandre.lureau@redhat.com>
Thu, 24 Aug 2017 08:46:10 +0000 (10:46 +0200)
committerMarkus Armbruster <armbru@redhat.com>
Mon, 4 Sep 2017 11:09:13 +0000 (13:09 +0200)
Currently, a FOO_lookup is an array of strings terminated by a NULL
sentinel.

A future patch will generate enums with "holes".  NULL-termination
will cease to work then.

To prepare for that, store the length in the FOO_lookup by wrapping it
in a struct and adding a member for the length.

The sentinel will be dropped next.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20170822132255.23945-13-marcandre.lureau@redhat.com>
[Basically redone]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <1503564371-26090-16-git-send-email-armbru@redhat.com>
[Rebased]

33 files changed:
backends/hostmem.c
block.c
block/blkdebug.c
block/file-posix.c
block/file-win32.c
block/gluster.c
block/parallels.c
block/qcow2.c
block/quorum.c
blockdev.c
crypto/block-luks.c
crypto/secret.c
crypto/tlscreds.c
hmp.c
hw/core/qdev-properties.c
include/hw/qdev-core.h
include/qapi/util.h
include/qapi/visitor.h
include/qom/object.h
migration/global_state.c
net/filter.c
qapi/qapi-util.c
qapi/qapi-visit-core.c
qemu-img.c
qemu-nbd.c
qom/object.c
scripts/qapi-visit.py
scripts/qapi.py
tests/check-qom-proplist.c
tests/qmp-test.c
tests/test-qapi-util.c
tests/test-qobject-input-visitor.c
tpm.c

index 06e8898e403f63910dd3cb3f4b08354298ee344a..217cff67662b65ca29972a4ecb8f6e5d408287e1 100644 (file)
@@ -395,7 +395,7 @@ host_memory_backend_class_init(ObjectClass *oc, void *data)
         host_memory_backend_set_host_nodes,
         NULL, NULL, &error_abort);
     object_class_property_add_enum(oc, "policy", "HostMemPolicy",
-        HostMemPolicy_lookup,
+        &HostMemPolicy_lookup,
         host_memory_backend_get_policy,
         host_memory_backend_set_policy, &error_abort);
     object_class_property_add_str(oc, "id", get_id, set_id, &error_abort);
diff --git a/block.c b/block.c
index 845eff817793baad085cacd8623d20b1842d6555..b749bd640420b484ed1cbfc8dfd52acd52be8ff4 100644 (file)
--- a/block.c
+++ b/block.c
@@ -1332,7 +1332,7 @@ static int bdrv_open_common(BlockDriverState *bs, BlockBackend *file,
     detect_zeroes = qemu_opt_get(opts, "detect-zeroes");
     if (detect_zeroes) {
         BlockdevDetectZeroesOptions value =
-            qapi_enum_parse(BlockdevDetectZeroesOptions_lookup,
+            qapi_enum_parse(&BlockdevDetectZeroesOptions_lookup,
                             detect_zeroes,
                             BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF,
                             &local_err);
index b370fcedfbc95093b26012724e759693b139ea28..8e385acf54678376197070531ad340301030db8a 100644 (file)
@@ -169,7 +169,7 @@ static int add_rule(void *opaque, QemuOpts *opts, Error **errp)
         error_setg(errp, "Missing event name for rule");
         return -1;
     }
-    event = qapi_enum_parse(BlkdebugEvent_lookup, event_name, -1, errp);
+    event = qapi_enum_parse(&BlkdebugEvent_lookup, event_name, -1, errp);
     if (event < 0) {
         return -1;
     }
@@ -732,7 +732,7 @@ static int blkdebug_debug_breakpoint(BlockDriverState *bs, const char *event,
     struct BlkdebugRule *rule;
     int blkdebug_event;
 
-    blkdebug_event = qapi_enum_parse(BlkdebugEvent_lookup, event, -1, NULL);
+    blkdebug_event = qapi_enum_parse(&BlkdebugEvent_lookup, event, -1, NULL);
     if (blkdebug_event < 0) {
         return -ENOENT;
     }
index bfef91db634b0c7a2ed87fbbf7abccfc4791784c..6acbd56238b5fa2f534dec839fdf61350da3e364 100644 (file)
@@ -437,7 +437,8 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
     aio_default = (bdrv_flags & BDRV_O_NATIVE_AIO)
                   ? BLOCKDEV_AIO_OPTIONS_NATIVE
                   : BLOCKDEV_AIO_OPTIONS_THREADS;
-    aio = qapi_enum_parse(BlockdevAioOptions_lookup, qemu_opt_get(opts, "aio"),
+    aio = qapi_enum_parse(&BlockdevAioOptions_lookup,
+                          qemu_opt_get(opts, "aio"),
                           aio_default, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
@@ -446,7 +447,8 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
     }
     s->use_linux_aio = (aio == BLOCKDEV_AIO_OPTIONS_NATIVE);
 
-    locking = qapi_enum_parse(OnOffAuto_lookup, qemu_opt_get(opts, "locking"),
+    locking = qapi_enum_parse(&OnOffAuto_lookup,
+                              qemu_opt_get(opts, "locking"),
                               ON_OFF_AUTO_AUTO, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
@@ -1973,7 +1975,7 @@ static int raw_create(const char *filename, QemuOpts *opts, Error **errp)
                           BDRV_SECTOR_SIZE);
     nocow = qemu_opt_get_bool(opts, BLOCK_OPT_NOCOW, false);
     buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
-    prealloc = qapi_enum_parse(PreallocMode_lookup, buf,
+    prealloc = qapi_enum_parse(&PreallocMode_lookup, buf,
                                PREALLOC_MODE_OFF, &local_err);
     g_free(buf);
     if (local_err) {
index f2a1830060060dbf716ad8c6996bc325f75f006e..9e02214a69bea59eb6eb33c34aebf83bba0de115 100644 (file)
@@ -302,7 +302,7 @@ static bool get_aio_option(QemuOpts *opts, int flags, Error **errp)
 
     aio_default = (flags & BDRV_O_NATIVE_AIO) ? BLOCKDEV_AIO_OPTIONS_NATIVE
                                               : BLOCKDEV_AIO_OPTIONS_THREADS;
-    aio = qapi_enum_parse(BlockdevAioOptions_lookup, qemu_opt_get(opts, "aio"),
+    aio = qapi_enum_parse(&BlockdevAioOptions_lookup, qemu_opt_get(opts, "aio"),
                           aio_default, errp);
 
     switch (aio) {
index 29f9427e47f9eb350067947db75f7e6898b37f5e..0f4265a3a41e49e3939ff37350ffae84ec9887ed 100644 (file)
@@ -543,7 +543,7 @@ static int qemu_gluster_parse_json(BlockdevOptionsGluster *gconf,
         if (!strcmp(ptr, "tcp")) {
             ptr = "inet";       /* accept legacy "tcp" */
         }
-        type = qapi_enum_parse(SocketAddressType_lookup, ptr, -1, NULL);
+        type = qapi_enum_parse(&SocketAddressType_lookup, ptr, -1, NULL);
         if (type != SOCKET_ADDRESS_TYPE_INET
             && type != SOCKET_ADDRESS_TYPE_UNIX) {
             error_setg(&local_err,
@@ -1000,7 +1000,7 @@ static int qemu_gluster_create(const char *filename,
                           BDRV_SECTOR_SIZE);
 
     tmp = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
-    prealloc = qapi_enum_parse(PreallocMode_lookup, tmp, PREALLOC_MODE_OFF,
+    prealloc = qapi_enum_parse(&PreallocMode_lookup, tmp, PREALLOC_MODE_OFF,
                                &local_err);
     g_free(tmp);
     if (local_err) {
index d812210b4fbfb8259a36a2a21488afb3d2e5c497..cce7336cac15f3eb5fc5f6b70f33d0ce7de3ad86 100644 (file)
@@ -68,13 +68,15 @@ typedef enum ParallelsPreallocMode {
     PRL_PREALLOC_MODE__MAX = 2,
 } ParallelsPreallocMode;
 
-static const char *prealloc_mode_lookup[] = {
-    "falloc",
-    "truncate",
-    NULL,
+static QEnumLookup prealloc_mode_lookup = {
+    .array = (const char *const[]) {
+        "falloc",
+        "truncate",
+        NULL,
+    },
+    .size = PRL_PREALLOC_MODE__MAX
 };
 
-
 typedef struct BDRVParallelsState {
     /** Locking is conservative, the lock protects
      *   - image file extending (truncate, fallocate)
@@ -695,7 +697,7 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
         qemu_opt_get_size_del(opts, PARALLELS_OPT_PREALLOC_SIZE, 0);
     s->prealloc_size = MAX(s->tracks, s->prealloc_size >> BDRV_SECTOR_BITS);
     buf = qemu_opt_get_del(opts, PARALLELS_OPT_PREALLOC_MODE);
-    s->prealloc_mode = qapi_enum_parse(prealloc_mode_lookup, buf,
+    s->prealloc_mode = qapi_enum_parse(&prealloc_mode_lookup, buf,
                                        PRL_PREALLOC_MODE_FALLOCATE,
                                        &local_err);
     g_free(buf);
index cbe9681fb0fae0068577b8f26b1bc62a0277e2fd..2ec399663e1397c5f16dce62f5eaad0168066e5c 100644 (file)
@@ -2915,7 +2915,7 @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp)
         goto finish;
     }
     buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
-    prealloc = qapi_enum_parse(PreallocMode_lookup, buf,
+    prealloc = qapi_enum_parse(&PreallocMode_lookup, buf,
                                PREALLOC_MODE_OFF, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
@@ -3605,7 +3605,7 @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,
     }
 
     optstr = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
-    prealloc = qapi_enum_parse(PreallocMode_lookup, optstr,
+    prealloc = qapi_enum_parse(&PreallocMode_lookup, optstr,
                                PREALLOC_MODE_OFF, &local_err);
     g_free(optstr);
     if (local_err) {
index 8d1c9f630609d6b90371a81e95c7b882ad501320..272f9a5b7703ec247973869a18a39ab98abebe38 100644 (file)
@@ -912,7 +912,7 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags,
     if (!pattern_str) {
         ret = QUORUM_READ_PATTERN_QUORUM;
     } else {
-        ret = qapi_enum_parse(QuorumReadPattern_lookup, pattern_str,
+        ret = qapi_enum_parse(&QuorumReadPattern_lookup, pattern_str,
                               -EINVAL, NULL);
     }
     if (ret < 0) {
index bfb2a95299ce59f349acc98d96a81b15c49fdbc2..796beaed9458de389712bce75f89a6748dc6fae8 100644 (file)
@@ -437,7 +437,7 @@ static void extract_common_blockdev_options(QemuOpts *opts, int *bdrv_flags,
 
     if (detect_zeroes) {
         *detect_zeroes =
-            qapi_enum_parse(BlockdevDetectZeroesOptions_lookup,
+            qapi_enum_parse(&BlockdevDetectZeroesOptions_lookup,
                             qemu_opt_get(opts, "detect-zeroes"),
                             BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF,
                             &local_error);
index 4e828951d416528edbf38bd069e33bdbef6244b3..36bc856084d0ad86016fc6aabf999000774d8ae6 100644 (file)
@@ -264,7 +264,7 @@ qcrypto_block_luks_cipher_alg_lookup(QCryptoCipherAlgorithm alg,
 /* XXX replace with qapi_enum_parse() in future, when we can
  * make that function emit a more friendly error message */
 static int qcrypto_block_luks_name_lookup(const char *name,
-                                          const char *const *map,
+                                          const QEnumLookup *map,
                                           const char *type,
                                           Error **errp)
 {
@@ -279,19 +279,19 @@ static int qcrypto_block_luks_name_lookup(const char *name,
 
 #define qcrypto_block_luks_cipher_mode_lookup(name, errp)               \
     qcrypto_block_luks_name_lookup(name,                                \
-                                   QCryptoCipherMode_lookup,            \
+                                   &QCryptoCipherMode_lookup,           \
                                    "Cipher mode",                       \
                                    errp)
 
 #define qcrypto_block_luks_hash_name_lookup(name, errp)                 \
     qcrypto_block_luks_name_lookup(name,                                \
-                                   QCryptoHashAlgorithm_lookup,         \
+                                   &QCryptoHashAlgorithm_lookup,        \
                                    "Hash algorithm",                    \
                                    errp)
 
 #define qcrypto_block_luks_ivgen_name_lookup(name, errp)                \
     qcrypto_block_luks_name_lookup(name,                                \
-                                   QCryptoIVGenAlgorithm_lookup,        \
+                                   &QCryptoIVGenAlgorithm_lookup,       \
                                    "IV generator",                      \
                                    errp)
 
index 285ab7a63c8f1f4b0f86fe30874580521eaca359..388abd7df5f0d78fb71cc95e4b23f492f5fc2c76 100644 (file)
@@ -378,7 +378,7 @@ qcrypto_secret_class_init(ObjectClass *oc, void *data)
                                    NULL);
     object_class_property_add_enum(oc, "format",
                                    "QCryptoSecretFormat",
-                                   QCryptoSecretFormat_lookup,
+                                   &QCryptoSecretFormat_lookup,
                                    qcrypto_secret_prop_get_format,
                                    qcrypto_secret_prop_set_format,
                                    NULL);
index a8965531b6a0928d33e23305aae0c1fddea0a3b7..3cd41035bbe831fb485b430d93f56fd1ae59e1f4 100644 (file)
@@ -233,7 +233,7 @@ qcrypto_tls_creds_class_init(ObjectClass *oc, void *data)
                                   NULL);
     object_class_property_add_enum(oc, "endpoint",
                                    "QCryptoTLSCredsEndpoint",
-                                   QCryptoTLSCredsEndpoint_lookup,
+                                   &QCryptoTLSCredsEndpoint_lookup,
                                    qcrypto_tls_creds_prop_get_endpoint,
                                    qcrypto_tls_creds_prop_set_endpoint,
                                    NULL);
diff --git a/hmp.c b/hmp.c
index 30819fe602ff1aa027b792b677dbd0685b03fac2..cd046c6d714cb26a88eecb8cf81399202fa926df 100644 (file)
--- a/hmp.c
+++ b/hmp.c
@@ -1528,7 +1528,7 @@ void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict)
     MigrationCapabilityStatusList *caps = g_malloc0(sizeof(*caps));
     int val;
 
-    val = qapi_enum_parse(MigrationCapability_lookup, cap, -1, &err);
+    val = qapi_enum_parse(&MigrationCapability_lookup, cap, -1, &err);
     if (val < 0) {
         goto end;
     }
@@ -1557,7 +1557,7 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
     Error *err = NULL;
     int val, ret;
 
-    val = qapi_enum_parse(MigrationParameter_lookup, param, -1, &err);
+    val = qapi_enum_parse(&MigrationParameter_lookup, param, -1, &err);
     if (val < 0) {
         goto cleanup;
     }
@@ -1735,7 +1735,7 @@ void hmp_change(Monitor *mon, const QDict *qdict)
     } else {
         if (read_only) {
             read_only_mode =
-                qapi_enum_parse(BlockdevChangeReadOnlyMode_lookup,
+                qapi_enum_parse(&BlockdevChangeReadOnlyMode_lookup,
                                 read_only,
                                 BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN, &err);
             if (err) {
index 7512bd43793596736d6464340d7946282b403482..1dc80fcea2afd343424bcf47e057383261087161 100644 (file)
@@ -587,7 +587,7 @@ const PropertyInfo qdev_prop_macaddr = {
 const PropertyInfo qdev_prop_on_off_auto = {
     .name = "OnOffAuto",
     .description = "on/off/auto",
-    .enum_table = OnOffAuto_lookup,
+    .enum_table = &OnOffAuto_lookup,
     .get = get_enum,
     .set = set_enum,
     .set_default_value = set_default_value_enum,
@@ -599,7 +599,7 @@ QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
 
 const PropertyInfo qdev_prop_losttickpolicy = {
     .name  = "LostTickPolicy",
-    .enum_table  = LostTickPolicy_lookup,
+    .enum_table  = &LostTickPolicy_lookup,
     .get   = get_enum,
     .set   = set_enum,
     .set_default_value = set_default_value_enum,
@@ -613,7 +613,7 @@ const PropertyInfo qdev_prop_blockdev_on_error = {
     .name = "BlockdevOnError",
     .description = "Error handling policy, "
                    "report/ignore/enospc/stop/auto",
-    .enum_table = BlockdevOnError_lookup,
+    .enum_table = &BlockdevOnError_lookup,
     .get = get_enum,
     .set = set_enum,
     .set_default_value = set_default_value_enum,
@@ -627,7 +627,7 @@ const PropertyInfo qdev_prop_bios_chs_trans = {
     .name = "BiosAtaTranslation",
     .description = "Logical CHS translation algorithm, "
                    "auto/none/lba/large/rechs",
-    .enum_table = BiosAtaTranslation_lookup,
+    .enum_table = &BiosAtaTranslation_lookup,
     .get = get_enum,
     .set = set_enum,
     .set_default_value = set_default_value_enum,
@@ -639,7 +639,7 @@ const PropertyInfo qdev_prop_fdc_drive_type = {
     .name = "FdcDriveType",
     .description = "FDC drive type, "
                    "144/288/120/none/auto",
-    .enum_table = FloppyDriveType_lookup,
+    .enum_table = &FloppyDriveType_lookup,
     .get = get_enum,
     .set = set_enum,
     .set_default_value = set_default_value_enum,
index ae317286a480154a0cd3330f7ecfb4a6fea4e18e..089146197f9eb38d7437f1c052094ec6fe24b38c 100644 (file)
@@ -249,7 +249,7 @@ struct Property {
 struct PropertyInfo {
     const char *name;
     const char *description;
-    const char * const *enum_table;
+    const QEnumLookup *enum_table;
     int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len);
     void (*set_default_value)(Object *obj, const Property *prop);
     void (*create)(Object *obj, Property *prop, Error **errp);
index 5e50d0c1ce8f0e6c3f84bfa8e59fe0f7c52c878f..a7c3c641487462c0945ab1ee71bb6fdf1adb33ed 100644 (file)
 #ifndef QAPI_UTIL_H
 #define QAPI_UTIL_H
 
-const char *qapi_enum_lookup(const char *const lookup[], int val);
-int qapi_enum_parse(const char * const lookup[], const char *buf,
+typedef struct QEnumLookup {
+    const char *const *array;
+    int size;
+} QEnumLookup;
+
+const char *qapi_enum_lookup(const QEnumLookup *lookup, int val);
+int qapi_enum_parse(const QEnumLookup *lookup, const char *buf,
                     int def, Error **errp);
 
 int parse_qapi_name(const char *name, bool complete);
index 0f3b8cb459fcdf46fa1c82644b30e0d3433dc379..62a51a54cb3c9af50536db1079abba2582a28659 100644 (file)
@@ -469,7 +469,7 @@ bool visit_optional(Visitor *v, const char *name, bool *present);
  * that visit_type_str() must have no unwelcome side effects.
  */
 void visit_type_enum(Visitor *v, const char *name, int *obj,
-                     const char *const strings[], Error **errp);
+                     const QEnumLookup *lookup, Error **errp);
 
 /*
  * Check if visitor is an input visitor.
index 1b828994fa3a89a2f58a891aac8e20c779f0ab57..f3e5cff37a3a328c75371e98f891c3db3663c630 100644 (file)
@@ -1415,14 +1415,14 @@ void object_class_property_add_bool(ObjectClass *klass, const char *name,
  */
 void object_property_add_enum(Object *obj, const char *name,
                               const char *typename,
-                              const char * const *strings,
+                              const QEnumLookup *lookup,
                               int (*get)(Object *, Error **),
                               void (*set)(Object *, int, Error **),
                               Error **errp);
 
 void object_class_property_add_enum(ObjectClass *klass, const char *name,
                                     const char *typename,
-                                    const char * const *strings,
+                                    const QEnumLookup *lookup,
                                     int (*get)(Object *, Error **),
                                     void (*set)(Object *, int, Error **),
                                     Error **errp);
index 8db2f194593d1d2755eacae4f792e9ecf9720614..dfdaf63910668249e8a215c14bb06fa26cf0b31c 100644 (file)
@@ -88,7 +88,7 @@ static int global_state_post_load(void *opaque, int version_id)
     s->received = true;
     trace_migrate_global_state_post_load(runstate);
 
-    r = qapi_enum_parse(RunState_lookup, runstate, -1, &local_err);
+    r = qapi_enum_parse(&RunState_lookup, runstate, -1, &local_err);
 
     if (r == -1) {
         if (local_err) {
index 1dfd2caa235058b57c02e72b2fc8adbcba3f6cd3..2fd7d7d66318836c77907e4d84408d4557de7f26 100644 (file)
@@ -179,7 +179,7 @@ static void netfilter_init(Object *obj)
                             netfilter_get_netdev_id, netfilter_set_netdev_id,
                             NULL);
     object_property_add_enum(obj, "queue", "NetFilterDirection",
-                             NetFilterDirection_lookup,
+                             &NetFilterDirection_lookup,
                              netfilter_get_direction, netfilter_set_direction,
                              NULL);
     object_property_add_str(obj, "status",
index 7af2f04d3666c82605684316d6ee18920c46ec40..e9b266bb70962b1c37141ce2ca006645ad83e72e 100644 (file)
 #include "qapi/error.h"
 #include "qemu-common.h"
 
-const char *qapi_enum_lookup(const char *const lookup[], int val)
+const char *qapi_enum_lookup(const QEnumLookup *lookup, int val)
 {
-    assert(val >= 0);
+    assert(val >= 0 && val < lookup->size);
 
-    return lookup[val];
+    return lookup->array[val];
 }
 
-int qapi_enum_parse(const char * const lookup[], const char *buf,
+int qapi_enum_parse(const QEnumLookup *lookup, const char *buf,
                     int def, Error **errp)
 {
     int i;
@@ -30,8 +30,8 @@ int qapi_enum_parse(const char * const lookup[], const char *buf,
         return def;
     }
 
-    for (i = 0; lookup[i]; i++) {
-        if (!strcmp(buf, lookup[i])) {
+    for (i = 0; i < lookup->size; i++) {
+        if (!strcmp(buf, lookup->array[i])) {
             return i;
         }
     }
index 30dc85b6f39e5eea43c2234fef7705a15cf31b39..3dcb9688674d84dadd77fa28b3edad9baebf0ae9 100644 (file)
@@ -333,24 +333,26 @@ void visit_type_null(Visitor *v, const char *name, QNull **obj,
 }
 
 static void output_type_enum(Visitor *v, const char *name, int *obj,
-                             const char *const strings[], Error **errp)
+                             const QEnumLookup *lookup, Error **errp)
 {
-    int i = 0;
     int value = *obj;
     char *enum_str;
 
-    while (strings[i++] != NULL);
-    if (value < 0 || value >= i - 1) {
+    /*
+     * TODO why is this an error, not an assertion?  If assertion:
+     * delete, and rely on qapi_enum_lookup()
+     */
+    if (value < 0 || value >= lookup->size) {
         error_setg(errp, QERR_INVALID_PARAMETER, name ? name : "null");
         return;
     }
 
-    enum_str = (char *)qapi_enum_lookup(strings, value);
+    enum_str = (char *)qapi_enum_lookup(lookup, value);
     visit_type_str(v, name, &enum_str, errp);
 }
 
 static void input_type_enum(Visitor *v, const char *name, int *obj,
-                            const char *const strings[], Error **errp)
+                            const QEnumLookup *lookup, Error **errp)
 {
     Error *local_err = NULL;
     int64_t value;
@@ -362,7 +364,7 @@ static void input_type_enum(Visitor *v, const char *name, int *obj,
         return;
     }
 
-    value = qapi_enum_parse(strings, enum_str, -1, NULL);
+    value = qapi_enum_parse(lookup, enum_str, -1, NULL);
     if (value < 0) {
         error_setg(errp, QERR_INVALID_PARAMETER, enum_str);
         g_free(enum_str);
@@ -374,16 +376,16 @@ static void input_type_enum(Visitor *v, const char *name, int *obj,
 }
 
 void visit_type_enum(Visitor *v, const char *name, int *obj,
-                     const char *const strings[], Error **errp)
+                     const QEnumLookup *lookup, Error **errp)
 {
-    assert(obj && strings);
+    assert(obj && lookup);
     trace_visit_type_enum(v, name, obj);
     switch (v->type) {
     case VISITOR_INPUT:
-        input_type_enum(v, name, obj, strings, errp);
+        input_type_enum(v, name, obj, lookup, errp);
         break;
     case VISITOR_OUTPUT:
-        output_type_enum(v, name, obj, strings, errp);
+        output_type_enum(v, name, obj, lookup, errp);
         break;
     case VISITOR_CLONE:
         /* nothing further to do, scalar value was already copied by
index a72a2e3133792a707567a45373339fa45739a13a..df984b11b904b63f93e7dc260f2cd15a1fceb4b2 100644 (file)
@@ -3489,7 +3489,7 @@ static int img_resize(int argc, char **argv)
             image_opts = true;
             break;
         case OPTION_PREALLOCATION:
-            prealloc = qapi_enum_parse(PreallocMode_lookup, optarg,
+            prealloc = qapi_enum_parse(&PreallocMode_lookup, optarg,
                                        PREALLOC_MODE__MAX, NULL);
             if (prealloc == PREALLOC_MODE__MAX) {
                 error_report("Invalid preallocation mode '%s'", optarg);
index a97f3f45404e12044de387704d70d20e3ad490b3..d75ca514820760a6852d9f4983788634a28402a7 100644 (file)
@@ -638,7 +638,7 @@ int main(int argc, char **argv)
             break;
         case QEMU_NBD_OPT_DETECT_ZEROES:
             detect_zeroes =
-                qapi_enum_parse(BlockdevDetectZeroesOptions_lookup,
+                qapi_enum_parse(&BlockdevDetectZeroesOptions_lookup,
                                 optarg,
                                 BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF,
                                 &local_err);
index fe6e744b4dcd832ab069805d941f1b39dd81feb1..3e18537e9b801695d05f86a6fb26846ed18ac5a9 100644 (file)
@@ -1246,7 +1246,7 @@ uint64_t object_property_get_uint(Object *obj, const char *name,
 }
 
 typedef struct EnumProperty {
-    const char * const *strings;
+    const QEnumLookup *lookup;
     int (*get)(Object *, Error **);
     void (*set)(Object *, int, Error **);
 } EnumProperty;
@@ -1284,7 +1284,7 @@ int object_property_get_enum(Object *obj, const char *name,
     visit_complete(v, &str);
     visit_free(v);
     v = string_input_visitor_new(str);
-    visit_type_enum(v, name, &ret, enumprop->strings, errp);
+    visit_type_enum(v, name, &ret, enumprop->lookup, errp);
 
     g_free(str);
     visit_free(v);
@@ -1950,7 +1950,7 @@ static void property_get_enum(Object *obj, Visitor *v, const char *name,
         return;
     }
 
-    visit_type_enum(v, name, &value, prop->strings, errp);
+    visit_type_enum(v, name, &value, prop->lookup, errp);
 }
 
 static void property_set_enum(Object *obj, Visitor *v, const char *name,
@@ -1960,7 +1960,7 @@ static void property_set_enum(Object *obj, Visitor *v, const char *name,
     int value;
     Error *err = NULL;
 
-    visit_type_enum(v, name, &value, prop->strings, &err);
+    visit_type_enum(v, name, &value, prop->lookup, &err);
     if (err) {
         error_propagate(errp, err);
         return;
@@ -1977,7 +1977,7 @@ static void property_release_enum(Object *obj, const char *name,
 
 void object_property_add_enum(Object *obj, const char *name,
                               const char *typename,
-                              const char * const *strings,
+                              const QEnumLookup *lookup,
                               int (*get)(Object *, Error **),
                               void (*set)(Object *, int, Error **),
                               Error **errp)
@@ -1985,7 +1985,7 @@ void object_property_add_enum(Object *obj, const char *name,
     Error *local_err = NULL;
     EnumProperty *prop = g_malloc(sizeof(*prop));
 
-    prop->strings = strings;
+    prop->lookup = lookup;
     prop->get = get;
     prop->set = set;
 
@@ -2002,7 +2002,7 @@ void object_property_add_enum(Object *obj, const char *name,
 
 void object_class_property_add_enum(ObjectClass *klass, const char *name,
                                     const char *typename,
-                                    const char * const *strings,
+                                    const QEnumLookup *lookup,
                                     int (*get)(Object *, Error **),
                                     void (*set)(Object *, int, Error **),
                                     Error **errp)
@@ -2010,7 +2010,7 @@ void object_class_property_add_enum(ObjectClass *klass, const char *name,
     Error *local_err = NULL;
     EnumProperty *prop = g_malloc(sizeof(*prop));
 
-    prop->strings = strings;
+    prop->lookup = lookup;
     prop->get = get;
     prop->set = set;
 
index bd0b7422366cec53b4081429efa3adf5f7814999..7e1cfc13f084a0670ccf0d23fbf4e4812f1e85b9 100644 (file)
@@ -153,7 +153,7 @@ def gen_visit_enum(name):
 void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s *obj, Error **errp)
 {
     int value = *obj;
-    visit_type_enum(v, name, &value, %(c_name)s_lookup, errp);
+    visit_type_enum(v, name, &value, &%(c_name)s_lookup, errp);
     *obj = value;
 }
 ''',
index 8736b9c7862611942e0bb999e06ee5f4e212a4e3..39a67270fcc53df105a6df230abd7777e1813b51 100644 (file)
@@ -1849,19 +1849,22 @@ def guardend(name):
 def gen_enum_lookup(name, values, prefix=None):
     ret = mcgen('''
 
-const char *const %(c_name)s_lookup[] = {
+const QEnumLookup %(c_name)s_lookup = {
+    .array = (const char *const[]) {
 ''',
                 c_name=c_name(name))
     for value in values:
         index = c_enum_const(name, value, prefix)
         ret += mcgen('''
-    [%(index)s] = "%(value)s",
+        [%(index)s] = "%(value)s",
 ''',
                      index=index, value=value)
 
     max_index = c_enum_const(name, '_MAX', prefix)
     ret += mcgen('''
-    [%(max_index)s] = NULL,
+        [%(max_index)s] = NULL,
+    },
+    .size = %(max_index)s
 };
 ''',
                  max_index=max_index)
@@ -1895,9 +1898,9 @@ typedef enum %(c_name)s {
     ret += mcgen('''
 
 #define %(c_name)s_str(val) \\
-    qapi_enum_lookup(%(c_name)s_lookup, (val))
+    qapi_enum_lookup(&%(c_name)s_lookup, (val))
 
-extern const char *const %(c_name)s_lookup[];
+extern const QEnumLookup %(c_name)s_lookup;
 ''',
                  c_name=c_name(name))
     return ret
index c51e6e734dd7b8d270b12833986304aced28f3af..07e351f95047443641bc413715f6e3fb028e0912 100644 (file)
@@ -46,11 +46,14 @@ enum DummyAnimal {
     DUMMY_LAST,
 };
 
-static const char *const dummy_animal_map[DUMMY_LAST + 1] = {
-    [DUMMY_FROG] = "frog",
-    [DUMMY_ALLIGATOR] = "alligator",
-    [DUMMY_PLATYPUS] = "platypus",
-    [DUMMY_LAST] = NULL,
+const QEnumLookup dummy_animal_map = {
+    .array = (const char *const[]) {
+        [DUMMY_FROG] = "frog",
+        [DUMMY_ALLIGATOR] = "alligator",
+        [DUMMY_PLATYPUS] = "platypus",
+        [DUMMY_LAST] = NULL,
+    },
+    .size = DUMMY_LAST
 };
 
 struct DummyObject {
@@ -142,7 +145,7 @@ static void dummy_class_init(ObjectClass *cls, void *data)
                                   NULL);
     object_class_property_add_enum(cls, "av",
                                    "DummyAnimal",
-                                   dummy_animal_map,
+                                   &dummy_animal_map,
                                    dummy_get_av,
                                    dummy_set_av,
                                    NULL);
index b5f21dfa57c213f1c12baa6b442289bb31dc542e..c5a5c10b417b077c4c275eb20559ea2ae9112baa 100644 (file)
@@ -181,7 +181,7 @@ static void test_query(const void *data)
         g_assert(qdict_haskey(resp, "return"));
     } else {
         g_assert(error);
-        g_assert_cmpint(qapi_enum_parse(QapiErrorClass_lookup, error_class,
+        g_assert_cmpint(qapi_enum_parse(&QapiErrorClass_lookup, error_class,
                                         -1, &error_abort),
                         ==, expected_error_class);
     }
index 0992bdb218898d0df97a88fed17552565f2abc5e..4b5e4f8bd36be06003036cfac82ea49f8278a623 100644 (file)
@@ -19,19 +19,19 @@ static void test_qapi_enum_parse(void)
     Error *err = NULL;
     int ret;
 
-    ret = qapi_enum_parse(QType_lookup, NULL, QTYPE_NONE, &error_abort);
+    ret = qapi_enum_parse(&QType_lookup, NULL, QTYPE_NONE, &error_abort);
     g_assert_cmpint(ret, ==, QTYPE_NONE);
 
-    ret = qapi_enum_parse(QType_lookup, "junk", -1, NULL);
+    ret = qapi_enum_parse(&QType_lookup, "junk", -1, NULL);
     g_assert_cmpint(ret, ==, -1);
 
-    ret = qapi_enum_parse(QType_lookup, "junk", -1, &err);
+    ret = qapi_enum_parse(&QType_lookup, "junk", -1, &err);
     error_free_or_abort(&err);
 
-    ret = qapi_enum_parse(QType_lookup, "none", -1, &error_abort);
+    ret = qapi_enum_parse(&QType_lookup, "none", -1, &error_abort);
     g_assert_cmpint(ret, ==, QTYPE_NONE);
 
-    ret = qapi_enum_parse(QType_lookup, QType_str(QTYPE__MAX - 1),
+    ret = qapi_enum_parse(&QType_lookup, QType_str(QTYPE__MAX - 1),
                           QTYPE__MAX - 1, &error_abort);
     g_assert_cmpint(ret, ==, QTYPE__MAX - 1);
 }
index f8720aa5eb7ab5e5d6a80021fe94514e1501323a..fe591814e4489e66896137f78793e789ee3dda38 100644 (file)
@@ -1110,7 +1110,7 @@ static void test_visitor_in_fail_struct_missing(TestInputVisitorData *data,
     error_free_or_abort(&err);
     visit_optional(v, "optional", &present);
     g_assert(!present);
-    visit_type_enum(v, "enum", &en, EnumOne_lookup, &err);
+    visit_type_enum(v, "enum", &en, &EnumOne_lookup, &err);
     error_free_or_abort(&err);
     visit_type_int(v, "i64", &i64, &err);
     error_free_or_abort(&err);
diff --git a/tpm.c b/tpm.c
index 111f1ca63f3f53c00d351afe24b40bb4b9791227..2d830d072ad9875b16fb3a24e0887e09a6a8828b 100644 (file)
--- a/tpm.c
+++ b/tpm.c
@@ -33,7 +33,7 @@ void tpm_register_model(enum TpmModel model)
 
 const TPMDriverOps *tpm_get_backend_driver(const char *type)
 {
-    int i = qapi_enum_parse(TpmType_lookup, type, -1, NULL);
+    int i = qapi_enum_parse(&TpmType_lookup, type, -1, NULL);
 
     return i >= 0 ? be_drivers[i] : NULL;
 }