qapi: Change data type of the FOO_lookup generated for enum FOO
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]
diff --git a/backends/hostmem.c b/backends/hostmem.c
index 06e8898..217cff6 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -395,7 +395,7 @@
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 845eff8..b749bd6 100644
--- a/block.c
+++ b/block.c
@@ -1332,7 +1332,7 @@
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);
diff --git a/block/blkdebug.c b/block/blkdebug.c
index b370fce..8e385ac 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -169,7 +169,7 @@
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 @@
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;
}
diff --git a/block/file-posix.c b/block/file-posix.c
index bfef91d..6acbd56 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -437,7 +437,8 @@
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 @@
}
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 @@
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) {
diff --git a/block/file-win32.c b/block/file-win32.c
index f2a1830..9e02214 100644
--- a/block/file-win32.c
+++ b/block/file-win32.c
@@ -302,7 +302,7 @@
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) {
diff --git a/block/gluster.c b/block/gluster.c
index 29f9427..0f4265a 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -543,7 +543,7 @@
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 @@
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) {
diff --git a/block/parallels.c b/block/parallels.c
index d812210..cce7336 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -68,13 +68,15 @@
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 @@
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);
diff --git a/block/qcow2.c b/block/qcow2.c
index cbe9681..2ec3996 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -2915,7 +2915,7 @@
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 @@
}
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) {
diff --git a/block/quorum.c b/block/quorum.c
index 8d1c9f6..272f9a5 100644
--- a/block/quorum.c
+++ b/block/quorum.c
@@ -912,7 +912,7 @@
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) {
diff --git a/blockdev.c b/blockdev.c
index bfb2a95..796beae 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -437,7 +437,7 @@
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);
diff --git a/crypto/block-luks.c b/crypto/block-luks.c
index 4e82895..36bc856 100644
--- a/crypto/block-luks.c
+++ b/crypto/block-luks.c
@@ -264,7 +264,7 @@
/* 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 @@
#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)
diff --git a/crypto/secret.c b/crypto/secret.c
index 285ab7a..388abd7 100644
--- a/crypto/secret.c
+++ b/crypto/secret.c
@@ -378,7 +378,7 @@
NULL);
object_class_property_add_enum(oc, "format",
"QCryptoSecretFormat",
- QCryptoSecretFormat_lookup,
+ &QCryptoSecretFormat_lookup,
qcrypto_secret_prop_get_format,
qcrypto_secret_prop_set_format,
NULL);
diff --git a/crypto/tlscreds.c b/crypto/tlscreds.c
index a896553..3cd4103 100644
--- a/crypto/tlscreds.c
+++ b/crypto/tlscreds.c
@@ -233,7 +233,7 @@
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 30819fe..cd046c6 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1528,7 +1528,7 @@
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 @@
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 @@
} 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) {
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 7512bd4..1dc80fc 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -587,7 +587,7 @@
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 @@
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 @@
.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 @@
.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 @@
.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,
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index ae31728..0891461 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -249,7 +249,7 @@
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);
diff --git a/include/qapi/util.h b/include/qapi/util.h
index 5e50d0c..a7c3c64 100644
--- a/include/qapi/util.h
+++ b/include/qapi/util.h
@@ -11,8 +11,13 @@
#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);
diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
index 0f3b8cb..62a51a5 100644
--- a/include/qapi/visitor.h
+++ b/include/qapi/visitor.h
@@ -469,7 +469,7 @@
* 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.
diff --git a/include/qom/object.h b/include/qom/object.h
index 1b82899..f3e5cff 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -1415,14 +1415,14 @@
*/
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);
diff --git a/migration/global_state.c b/migration/global_state.c
index 8db2f19..dfdaf63 100644
--- a/migration/global_state.c
+++ b/migration/global_state.c
@@ -88,7 +88,7 @@
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) {
diff --git a/net/filter.c b/net/filter.c
index 1dfd2ca..2fd7d7d 100644
--- a/net/filter.c
+++ b/net/filter.c
@@ -179,7 +179,7 @@
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",
diff --git a/qapi/qapi-util.c b/qapi/qapi-util.c
index 7af2f04..e9b266b 100644
--- a/qapi/qapi-util.c
+++ b/qapi/qapi-util.c
@@ -14,14 +14,14 @@
#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 @@
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;
}
}
diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
index 30dc85b..3dcb968 100644
--- a/qapi/qapi-visit-core.c
+++ b/qapi/qapi-visit-core.c
@@ -333,24 +333,26 @@
}
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 @@
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 @@
}
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
diff --git a/qemu-img.c b/qemu-img.c
index a72a2e3..df984b1 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -3489,7 +3489,7 @@
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);
diff --git a/qemu-nbd.c b/qemu-nbd.c
index a97f3f4..d75ca51 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -638,7 +638,7 @@
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);
diff --git a/qom/object.c b/qom/object.c
index fe6e744..3e18537 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1246,7 +1246,7 @@
}
typedef struct EnumProperty {
- const char * const *strings;
+ const QEnumLookup *lookup;
int (*get)(Object *, Error **);
void (*set)(Object *, int, Error **);
} EnumProperty;
@@ -1284,7 +1284,7 @@
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 @@
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 @@
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 @@
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 @@
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_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 @@
Error *local_err = NULL;
EnumProperty *prop = g_malloc(sizeof(*prop));
- prop->strings = strings;
+ prop->lookup = lookup;
prop->get = get;
prop->set = set;
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index bd0b742..7e1cfc1 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -153,7 +153,7 @@
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;
}
''',
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 8736b9c..39a6727 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -1849,19 +1849,22 @@
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 @@
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
diff --git a/tests/check-qom-proplist.c b/tests/check-qom-proplist.c
index c51e6e7..07e351f 100644
--- a/tests/check-qom-proplist.c
+++ b/tests/check-qom-proplist.c
@@ -46,11 +46,14 @@
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 @@
NULL);
object_class_property_add_enum(cls, "av",
"DummyAnimal",
- dummy_animal_map,
+ &dummy_animal_map,
dummy_get_av,
dummy_set_av,
NULL);
diff --git a/tests/qmp-test.c b/tests/qmp-test.c
index b5f21df..c5a5c10 100644
--- a/tests/qmp-test.c
+++ b/tests/qmp-test.c
@@ -181,7 +181,7 @@
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);
}
diff --git a/tests/test-qapi-util.c b/tests/test-qapi-util.c
index 0992bdb..4b5e4f8 100644
--- a/tests/test-qapi-util.c
+++ b/tests/test-qapi-util.c
@@ -19,19 +19,19 @@
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);
}
diff --git a/tests/test-qobject-input-visitor.c b/tests/test-qobject-input-visitor.c
index f8720aa..fe59181 100644
--- a/tests/test-qobject-input-visitor.c
+++ b/tests/test-qobject-input-visitor.c
@@ -1110,7 +1110,7 @@
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 111f1ca..2d830d0 100644
--- a/tpm.c
+++ b/tpm.c
@@ -33,7 +33,7 @@
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;
}