From 7549457200ec3871ee827765f4d3bbc8d903b2ec Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Wed, 18 Nov 2015 01:52:53 -0700 Subject: qapi: Remove dead visitor code Commit cbc95538 removed unused start_handle() and end_handle(), but forgot to remove their declarations. Signed-off-by: Eric Blake Message-Id: <1447836791-369-19-git-send-email-eblake@redhat.com> Signed-off-by: Markus Armbruster --- include/qapi/visitor.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include') diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h index cfc19a616e..a2ad66cf8f 100644 --- a/include/qapi/visitor.h +++ b/include/qapi/visitor.h @@ -27,9 +27,6 @@ typedef struct GenericList struct GenericList *next; } GenericList; -void visit_start_handle(Visitor *v, void **obj, const char *kind, - const char *name, Error **errp); -void visit_end_handle(Visitor *v, Error **errp); void visit_start_struct(Visitor *v, void **obj, const char *kind, const char *name, size_t size, Error **errp); void visit_end_struct(Visitor *v, Error **errp); -- cgit v1.2.3-55-g7522 From a31939e6c854e26e391efaec49c9d7f796369bbb Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Wed, 18 Nov 2015 01:52:54 -0700 Subject: blkdebug: Merge hand-rolled and qapi BlkdebugEvent enum No need to keep two separate enums, where editing one is likely to forget the other. Now that we can specify a qapi enum prefix, we don't even have to change the bulk of the uses. get_event_by_name() could perhaps be replaced by qapi_enum_parse(), but I left that for another day. CC: Kevin Wolf Signed-off-by: Eric Blake Message-Id: <1447836791-369-20-git-send-email-eblake@redhat.com> Signed-off-by: Markus Armbruster --- block.c | 2 +- block/blkdebug.c | 79 +++++++---------------------------------------- docs/blkdebug.txt | 7 +++-- include/block/block.h | 62 +------------------------------------ include/block/block_int.h | 2 +- qapi/block-core.json | 4 ++- 6 files changed, 21 insertions(+), 135 deletions(-) (limited to 'include') diff --git a/block.c b/block.c index 3a7324bb05..9971976c38 100644 --- a/block.c +++ b/block.c @@ -2851,7 +2851,7 @@ ImageInfoSpecific *bdrv_get_specific_info(BlockDriverState *bs) return NULL; } -void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event) +void bdrv_debug_event(BlockDriverState *bs, BlkdebugEvent event) { if (!bs || !bs->drv || !bs->drv->bdrv_debug_event) { return; diff --git a/block/blkdebug.c b/block/blkdebug.c index dee3a0edfc..6bcb7fac7a 100644 --- a/block/blkdebug.c +++ b/block/blkdebug.c @@ -36,7 +36,7 @@ typedef struct BDRVBlkdebugState { int state; int new_state; - QLIST_HEAD(, BlkdebugRule) rules[BLKDBG_EVENT_MAX]; + QLIST_HEAD(, BlkdebugRule) rules[BLKDBG_MAX]; QSIMPLEQ_HEAD(, BlkdebugRule) active_rules; QLIST_HEAD(, BlkdebugSuspendedReq) suspended_reqs; } BDRVBlkdebugState; @@ -64,7 +64,7 @@ enum { }; typedef struct BlkdebugRule { - BlkDebugEvent event; + BlkdebugEvent event; int action; int state; union { @@ -143,69 +143,12 @@ static QemuOptsList *config_groups[] = { NULL }; -static const char *event_names[BLKDBG_EVENT_MAX] = { - [BLKDBG_L1_UPDATE] = "l1_update", - [BLKDBG_L1_GROW_ALLOC_TABLE] = "l1_grow.alloc_table", - [BLKDBG_L1_GROW_WRITE_TABLE] = "l1_grow.write_table", - [BLKDBG_L1_GROW_ACTIVATE_TABLE] = "l1_grow.activate_table", - - [BLKDBG_L2_LOAD] = "l2_load", - [BLKDBG_L2_UPDATE] = "l2_update", - [BLKDBG_L2_UPDATE_COMPRESSED] = "l2_update_compressed", - [BLKDBG_L2_ALLOC_COW_READ] = "l2_alloc.cow_read", - [BLKDBG_L2_ALLOC_WRITE] = "l2_alloc.write", - - [BLKDBG_READ_AIO] = "read_aio", - [BLKDBG_READ_BACKING_AIO] = "read_backing_aio", - [BLKDBG_READ_COMPRESSED] = "read_compressed", - - [BLKDBG_WRITE_AIO] = "write_aio", - [BLKDBG_WRITE_COMPRESSED] = "write_compressed", - - [BLKDBG_VMSTATE_LOAD] = "vmstate_load", - [BLKDBG_VMSTATE_SAVE] = "vmstate_save", - - [BLKDBG_COW_READ] = "cow_read", - [BLKDBG_COW_WRITE] = "cow_write", - - [BLKDBG_REFTABLE_LOAD] = "reftable_load", - [BLKDBG_REFTABLE_GROW] = "reftable_grow", - [BLKDBG_REFTABLE_UPDATE] = "reftable_update", - - [BLKDBG_REFBLOCK_LOAD] = "refblock_load", - [BLKDBG_REFBLOCK_UPDATE] = "refblock_update", - [BLKDBG_REFBLOCK_UPDATE_PART] = "refblock_update_part", - [BLKDBG_REFBLOCK_ALLOC] = "refblock_alloc", - [BLKDBG_REFBLOCK_ALLOC_HOOKUP] = "refblock_alloc.hookup", - [BLKDBG_REFBLOCK_ALLOC_WRITE] = "refblock_alloc.write", - [BLKDBG_REFBLOCK_ALLOC_WRITE_BLOCKS] = "refblock_alloc.write_blocks", - [BLKDBG_REFBLOCK_ALLOC_WRITE_TABLE] = "refblock_alloc.write_table", - [BLKDBG_REFBLOCK_ALLOC_SWITCH_TABLE] = "refblock_alloc.switch_table", - - [BLKDBG_CLUSTER_ALLOC] = "cluster_alloc", - [BLKDBG_CLUSTER_ALLOC_BYTES] = "cluster_alloc_bytes", - [BLKDBG_CLUSTER_FREE] = "cluster_free", - - [BLKDBG_FLUSH_TO_OS] = "flush_to_os", - [BLKDBG_FLUSH_TO_DISK] = "flush_to_disk", - - [BLKDBG_PWRITEV_RMW_HEAD] = "pwritev_rmw.head", - [BLKDBG_PWRITEV_RMW_AFTER_HEAD] = "pwritev_rmw.after_head", - [BLKDBG_PWRITEV_RMW_TAIL] = "pwritev_rmw.tail", - [BLKDBG_PWRITEV_RMW_AFTER_TAIL] = "pwritev_rmw.after_tail", - [BLKDBG_PWRITEV] = "pwritev", - [BLKDBG_PWRITEV_ZERO] = "pwritev_zero", - [BLKDBG_PWRITEV_DONE] = "pwritev_done", - - [BLKDBG_EMPTY_IMAGE_PREPARE] = "empty_image_prepare", -}; - -static int get_event_by_name(const char *name, BlkDebugEvent *event) +static int get_event_by_name(const char *name, BlkdebugEvent *event) { int i; - for (i = 0; i < BLKDBG_EVENT_MAX; i++) { - if (!strcmp(event_names[i], name)) { + for (i = 0; i < BLKDBG_MAX; i++) { + if (!strcmp(BlkdebugEvent_lookup[i], name)) { *event = i; return 0; } @@ -224,7 +167,7 @@ static int add_rule(void *opaque, QemuOpts *opts, Error **errp) struct add_rule_data *d = opaque; BDRVBlkdebugState *s = d->s; const char* event_name; - BlkDebugEvent event; + BlkdebugEvent event; struct BlkdebugRule *rule; /* Find the right event for the rule */ @@ -564,7 +507,7 @@ static void blkdebug_close(BlockDriverState *bs) BlkdebugRule *rule, *next; int i; - for (i = 0; i < BLKDBG_EVENT_MAX; i++) { + for (i = 0; i < BLKDBG_MAX; i++) { QLIST_FOREACH_SAFE(rule, &s->rules[i], next, next) { remove_rule(rule); } @@ -627,13 +570,13 @@ static bool process_rule(BlockDriverState *bs, struct BlkdebugRule *rule, return injected; } -static void blkdebug_debug_event(BlockDriverState *bs, BlkDebugEvent event) +static void blkdebug_debug_event(BlockDriverState *bs, BlkdebugEvent event) { BDRVBlkdebugState *s = bs->opaque; struct BlkdebugRule *rule, *next; bool injected; - assert((int)event >= 0 && event < BLKDBG_EVENT_MAX); + assert((int)event >= 0 && event < BLKDBG_MAX); injected = false; s->new_state = s->state; @@ -648,7 +591,7 @@ static int blkdebug_debug_breakpoint(BlockDriverState *bs, const char *event, { BDRVBlkdebugState *s = bs->opaque; struct BlkdebugRule *rule; - BlkDebugEvent blkdebug_event; + BlkdebugEvent blkdebug_event; if (get_event_by_name(event, &blkdebug_event) < 0) { return -ENOENT; @@ -690,7 +633,7 @@ static int blkdebug_debug_remove_breakpoint(BlockDriverState *bs, BlkdebugRule *rule, *next; int i, ret = -ENOENT; - for (i = 0; i < BLKDBG_EVENT_MAX; i++) { + for (i = 0; i < BLKDBG_MAX; i++) { QLIST_FOREACH_SAFE(rule, &s->rules[i], next, next) { if (rule->action == ACTION_SUSPEND && !strcmp(rule->options.suspend.tag, tag)) { diff --git a/docs/blkdebug.txt b/docs/blkdebug.txt index b67a36d5c6..43d8e8f9c6 100644 --- a/docs/blkdebug.txt +++ b/docs/blkdebug.txt @@ -1,6 +1,6 @@ Block I/O error injection using blkdebug ---------------------------------------- -Copyright (C) 2014 Red Hat Inc +Copyright (C) 2014-2015 Red Hat Inc This work is licensed under the terms of the GNU GPL, version 2 or later. See the COPYING file in the top-level directory. @@ -92,8 +92,9 @@ The core events are: flush_to_disk - flush the host block device's disk cache -See block/blkdebug.c:event_names[] for the full list of events. You may need -to grep block driver source code to understand the meaning of specific events. +See qapi/block-core.json:BlkdebugEvent for the full list of events. +You may need to grep block driver source code to understand the +meaning of specific events. State transitions ----------------- diff --git a/include/block/block.h b/include/block/block.h index 3477328737..d048bbff44 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -520,66 +520,6 @@ void bdrv_op_block_all(BlockDriverState *bs, Error *reason); void bdrv_op_unblock_all(BlockDriverState *bs, Error *reason); bool bdrv_op_blocker_is_empty(BlockDriverState *bs); -typedef enum { - BLKDBG_L1_UPDATE, - - BLKDBG_L1_GROW_ALLOC_TABLE, - BLKDBG_L1_GROW_WRITE_TABLE, - BLKDBG_L1_GROW_ACTIVATE_TABLE, - - BLKDBG_L2_LOAD, - BLKDBG_L2_UPDATE, - BLKDBG_L2_UPDATE_COMPRESSED, - BLKDBG_L2_ALLOC_COW_READ, - BLKDBG_L2_ALLOC_WRITE, - - BLKDBG_READ_AIO, - BLKDBG_READ_BACKING_AIO, - BLKDBG_READ_COMPRESSED, - - BLKDBG_WRITE_AIO, - BLKDBG_WRITE_COMPRESSED, - - BLKDBG_VMSTATE_LOAD, - BLKDBG_VMSTATE_SAVE, - - BLKDBG_COW_READ, - BLKDBG_COW_WRITE, - - BLKDBG_REFTABLE_LOAD, - BLKDBG_REFTABLE_GROW, - BLKDBG_REFTABLE_UPDATE, - - BLKDBG_REFBLOCK_LOAD, - BLKDBG_REFBLOCK_UPDATE, - BLKDBG_REFBLOCK_UPDATE_PART, - BLKDBG_REFBLOCK_ALLOC, - BLKDBG_REFBLOCK_ALLOC_HOOKUP, - BLKDBG_REFBLOCK_ALLOC_WRITE, - BLKDBG_REFBLOCK_ALLOC_WRITE_BLOCKS, - BLKDBG_REFBLOCK_ALLOC_WRITE_TABLE, - BLKDBG_REFBLOCK_ALLOC_SWITCH_TABLE, - - BLKDBG_CLUSTER_ALLOC, - BLKDBG_CLUSTER_ALLOC_BYTES, - BLKDBG_CLUSTER_FREE, - - BLKDBG_FLUSH_TO_OS, - BLKDBG_FLUSH_TO_DISK, - - BLKDBG_PWRITEV_RMW_HEAD, - BLKDBG_PWRITEV_RMW_AFTER_HEAD, - BLKDBG_PWRITEV_RMW_TAIL, - BLKDBG_PWRITEV_RMW_AFTER_TAIL, - BLKDBG_PWRITEV, - BLKDBG_PWRITEV_ZERO, - BLKDBG_PWRITEV_DONE, - - BLKDBG_EMPTY_IMAGE_PREPARE, - - BLKDBG_EVENT_MAX, -} BlkDebugEvent; - #define BLKDBG_EVENT(child, evt) \ do { \ if (child) { \ @@ -587,7 +527,7 @@ typedef enum { } \ } while (0) -void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event); +void bdrv_debug_event(BlockDriverState *bs, BlkdebugEvent event); int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event, const char *tag); diff --git a/include/block/block_int.h b/include/block/block_int.h index 4012e36437..66e208d620 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -244,7 +244,7 @@ struct BlockDriver { int (*bdrv_amend_options)(BlockDriverState *bs, QemuOpts *opts, BlockDriverAmendStatusCB *status_cb); - void (*bdrv_debug_event)(BlockDriverState *bs, BlkDebugEvent event); + void (*bdrv_debug_event)(BlockDriverState *bs, BlkdebugEvent event); /* TODO Better pass a option string/QDict/QemuOpts to add any rule? */ int (*bdrv_debug_breakpoint)(BlockDriverState *bs, const char *event, diff --git a/qapi/block-core.json b/qapi/block-core.json index 5a23165dfa..18ba6a63ad 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -1776,8 +1776,10 @@ # @BlkdebugEvent # # Trigger events supported by blkdebug. +# +# Since: 2.0 ## -{ 'enum': 'BlkdebugEvent', +{ 'enum': 'BlkdebugEvent', 'prefix': 'BLKDBG', 'data': [ 'l1_update', 'l1_grow.alloc_table', 'l1_grow.write_table', 'l1_grow.activate_table', 'l2_load', 'l2_update', 'l2_update_compressed', 'l2_alloc.cow_read', 'l2_alloc.write', -- cgit v1.2.3-55-g7522 From 7fb1cf1606c78c9d5b538f29176fd5a101726a9d Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Wed, 18 Nov 2015 01:52:57 -0700 Subject: qapi: Don't let implicit enum MAX member collide Now that we guarantee the user doesn't have any enum values beginning with a single underscore, we can use that for our own purposes. Renaming ENUM_MAX to ENUM__MAX makes it obvious that the sentinel is generated. This patch was mostly generated by applying a temporary patch: |diff --git a/scripts/qapi.py b/scripts/qapi.py |index e6d014b..b862ec9 100644 |--- a/scripts/qapi.py |+++ b/scripts/qapi.py |@@ -1570,6 +1570,7 @@ const char *const %(c_name)s_lookup[] = { | max_index = c_enum_const(name, 'MAX', prefix) | ret += mcgen(''' | [%(max_index)s] = NULL, |+// %(max_index)s | }; | ''', | max_index=max_index) then running: $ cat qapi-{types,event}.c tests/test-qapi-types.c | sed -n 's,^// \(.*\)MAX,s|\1MAX|\1_MAX|g,p' > list $ git grep -l _MAX | xargs sed -i -f list The only things not generated are the changes in scripts/qapi.py. Rejecting enum members named 'MAX' is now useless, and will be dropped in the next patch. Signed-off-by: Eric Blake Message-Id: <1447836791-369-23-git-send-email-eblake@redhat.com> Reviewed-by: Juan Quintela [Rebased to current master, commit message tweaked] Signed-off-by: Markus Armbruster --- block/blkdebug.c | 10 +++++----- block/parallels.c | 4 ++-- block/qcow2.c | 2 +- block/quorum.c | 2 +- block/raw-posix.c | 2 +- blockdev.c | 2 +- docs/qapi-code-gen.txt | 4 ++-- hmp.c | 14 +++++++------- hw/char/escc.c | 2 +- hw/i386/pc_piix.c | 2 +- hw/i386/pc_q35.c | 2 +- hw/input/hid.c | 2 +- hw/input/ps2.c | 2 +- hw/input/virtio-input-hid.c | 8 ++++---- include/migration/migration.h | 4 ++-- migration/migration.c | 4 ++-- monitor.c | 14 +++++++------- net/net.c | 4 ++-- qemu-nbd.c | 2 +- replay/replay-input.c | 8 ++++---- scripts/qapi.py | 6 +++--- tests/test-qmp-output-visitor.c | 6 +++--- tests/test-string-output-visitor.c | 4 ++-- tpm.c | 10 +++++----- ui/cocoa.m | 2 +- ui/console.c | 2 +- ui/input-keymap.c | 4 ++-- ui/input-legacy.c | 6 +++--- ui/input.c | 6 +++--- ui/sdl.c | 2 +- ui/sdl2.c | 2 +- ui/spice-input.c | 2 +- ui/vnc.c | 2 +- vl.c | 18 +++++++++--------- 34 files changed, 83 insertions(+), 83 deletions(-) (limited to 'include') diff --git a/block/blkdebug.c b/block/blkdebug.c index 6bcb7fac7a..59c61eb6b2 100644 --- a/block/blkdebug.c +++ b/block/blkdebug.c @@ -36,7 +36,7 @@ typedef struct BDRVBlkdebugState { int state; int new_state; - QLIST_HEAD(, BlkdebugRule) rules[BLKDBG_MAX]; + QLIST_HEAD(, BlkdebugRule) rules[BLKDBG__MAX]; QSIMPLEQ_HEAD(, BlkdebugRule) active_rules; QLIST_HEAD(, BlkdebugSuspendedReq) suspended_reqs; } BDRVBlkdebugState; @@ -147,7 +147,7 @@ static int get_event_by_name(const char *name, BlkdebugEvent *event) { int i; - for (i = 0; i < BLKDBG_MAX; i++) { + for (i = 0; i < BLKDBG__MAX; i++) { if (!strcmp(BlkdebugEvent_lookup[i], name)) { *event = i; return 0; @@ -507,7 +507,7 @@ static void blkdebug_close(BlockDriverState *bs) BlkdebugRule *rule, *next; int i; - for (i = 0; i < BLKDBG_MAX; i++) { + for (i = 0; i < BLKDBG__MAX; i++) { QLIST_FOREACH_SAFE(rule, &s->rules[i], next, next) { remove_rule(rule); } @@ -576,7 +576,7 @@ static void blkdebug_debug_event(BlockDriverState *bs, BlkdebugEvent event) struct BlkdebugRule *rule, *next; bool injected; - assert((int)event >= 0 && event < BLKDBG_MAX); + assert((int)event >= 0 && event < BLKDBG__MAX); injected = false; s->new_state = s->state; @@ -633,7 +633,7 @@ static int blkdebug_debug_remove_breakpoint(BlockDriverState *bs, BlkdebugRule *rule, *next; int i, ret = -ENOENT; - for (i = 0; i < BLKDBG_MAX; i++) { + for (i = 0; i < BLKDBG__MAX; i++) { QLIST_FOREACH_SAFE(rule, &s->rules[i], next, next) { if (rule->action == ACTION_SUSPEND && !strcmp(rule->options.suspend.tag, tag)) { diff --git a/block/parallels.c b/block/parallels.c index f689fdeaff..e4a56a5141 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -61,7 +61,7 @@ typedef struct ParallelsHeader { typedef enum ParallelsPreallocMode { PRL_PREALLOC_MODE_FALLOCATE = 0, PRL_PREALLOC_MODE_TRUNCATE = 1, - PRL_PREALLOC_MODE_MAX = 2, + PRL_PREALLOC_MODE__MAX = 2, } ParallelsPreallocMode; static const char *prealloc_mode_lookup[] = { @@ -660,7 +660,7 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags, 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, - PRL_PREALLOC_MODE_MAX, PRL_PREALLOC_MODE_FALLOCATE, &local_err); + PRL_PREALLOC_MODE__MAX, PRL_PREALLOC_MODE_FALLOCATE, &local_err); g_free(buf); if (local_err != NULL) { goto fail_options; diff --git a/block/qcow2.c b/block/qcow2.c index 88f56c8868..5b59fa3d7f 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -2269,7 +2269,7 @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp) DEFAULT_CLUSTER_SIZE); buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); prealloc = qapi_enum_parse(PreallocMode_lookup, buf, - PREALLOC_MODE_MAX, PREALLOC_MODE_OFF, + PREALLOC_MODE__MAX, PREALLOC_MODE_OFF, &local_err); if (local_err) { error_propagate(errp, local_err); diff --git a/block/quorum.c b/block/quorum.c index b9ba028d46..d162459bd9 100644 --- a/block/quorum.c +++ b/block/quorum.c @@ -847,7 +847,7 @@ static int parse_read_pattern(const char *opt) return QUORUM_READ_PATTERN_QUORUM; } - for (i = 0; i < QUORUM_READ_PATTERN_MAX; i++) { + for (i = 0; i < QUORUM_READ_PATTERN__MAX; i++) { if (!strcmp(opt, QuorumReadPattern_lookup[i])) { return i; } diff --git a/block/raw-posix.c b/block/raw-posix.c index d9162fd306..ffeebe1a4c 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -1636,7 +1636,7 @@ static int raw_create(const char *filename, QemuOpts *opts, Error **errp) 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_MODE_MAX, PREALLOC_MODE_OFF, + PREALLOC_MODE__MAX, PREALLOC_MODE_OFF, &local_err); g_free(buf); if (local_err) { diff --git a/blockdev.c b/blockdev.c index 80932e8d8d..13eaa77037 100644 --- a/blockdev.c +++ b/blockdev.c @@ -454,7 +454,7 @@ static void extract_common_blockdev_options(QemuOpts *opts, int *bdrv_flags, *detect_zeroes = qapi_enum_parse(BlockdevDetectZeroesOptions_lookup, qemu_opt_get(opts, "detect-zeroes"), - BLOCKDEV_DETECT_ZEROES_OPTIONS_MAX, + BLOCKDEV_DETECT_ZEROES_OPTIONS__MAX, BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF, &local_error); if (local_error) { diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt index 32cc68fff1..2becba95b9 100644 --- a/docs/qapi-code-gen.txt +++ b/docs/qapi-code-gen.txt @@ -1053,7 +1053,7 @@ Example: const char *const example_QAPIEvent_lookup[] = { [EXAMPLE_QAPI_EVENT_MY_EVENT] = "MY_EVENT", - [EXAMPLE_QAPI_EVENT_MAX] = NULL, + [EXAMPLE_QAPI_EVENT__MAX] = NULL, }; $ cat qapi-generated/example-qapi-event.h [Uninteresting stuff omitted...] @@ -1070,7 +1070,7 @@ Example: typedef enum example_QAPIEvent { EXAMPLE_QAPI_EVENT_MY_EVENT = 0, - EXAMPLE_QAPI_EVENT_MAX = 1, + EXAMPLE_QAPI_EVENT__MAX = 1, } example_QAPIEvent; extern const char *const example_QAPIEvent_lookup[]; diff --git a/hmp.c b/hmp.c index 21406059c7..1b402c4b74 100644 --- a/hmp.c +++ b/hmp.c @@ -855,7 +855,7 @@ void hmp_info_tpm(Monitor *mon, const QDict *qdict) tpo->has_cancel_path ? ",cancel-path=" : "", tpo->has_cancel_path ? tpo->cancel_path : ""); break; - case TPM_TYPE_OPTIONS_KIND_MAX: + case TPM_TYPE_OPTIONS_KIND__MAX: break; } monitor_printf(mon, "\n"); @@ -1203,7 +1203,7 @@ void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict) MigrationCapabilityStatusList *caps = g_malloc0(sizeof(*caps)); int i; - for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) { + for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) { if (strcmp(cap, MigrationCapability_lookup[i]) == 0) { caps->value = g_malloc0(sizeof(*caps->value)); caps->value->capability = i; @@ -1214,7 +1214,7 @@ void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict) } } - if (i == MIGRATION_CAPABILITY_MAX) { + if (i == MIGRATION_CAPABILITY__MAX) { error_setg(&err, QERR_INVALID_PARAMETER, cap); } @@ -1239,7 +1239,7 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict) bool has_x_cpu_throttle_increment = false; int i; - for (i = 0; i < MIGRATION_PARAMETER_MAX; i++) { + for (i = 0; i < MIGRATION_PARAMETER__MAX; i++) { if (strcmp(param, MigrationParameter_lookup[i]) == 0) { switch (i) { case MIGRATION_PARAMETER_COMPRESS_LEVEL: @@ -1268,7 +1268,7 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict) } } - if (i == MIGRATION_PARAMETER_MAX) { + if (i == MIGRATION_PARAMETER__MAX) { error_setg(&err, QERR_INVALID_PARAMETER, param); } @@ -1368,7 +1368,7 @@ void hmp_change(Monitor *mon, const QDict *qdict) if (read_only) { read_only_mode = qapi_enum_parse(BlockdevChangeReadOnlyMode_lookup, - read_only, BLOCKDEV_CHANGE_READ_ONLY_MODE_MAX, + read_only, BLOCKDEV_CHANGE_READ_ONLY_MODE__MAX, BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN, &err); if (err) { hmp_handle_error(mon, &err); @@ -1771,7 +1771,7 @@ void hmp_sendkey(Monitor *mon, const QDict *qdict) keylist->value->u.number = value; } else { int idx = index_from_key(keyname_buf); - if (idx == Q_KEY_CODE_MAX) { + if (idx == Q_KEY_CODE__MAX) { goto err_out; } keylist->value->type = KEY_VALUE_KIND_QCODE; diff --git a/hw/char/escc.c b/hw/char/escc.c index c9840e11da..b35121461a 100644 --- a/hw/char/escc.c +++ b/hw/char/escc.c @@ -714,7 +714,7 @@ MemoryRegion *escc_init(hwaddr base, qemu_irq irqA, qemu_irq irqB, return &d->mmio; } -static const uint8_t qcode_to_keycode[Q_KEY_CODE_MAX] = { +static const uint8_t qcode_to_keycode[Q_KEY_CODE__MAX] = { [Q_KEY_CODE_SHIFT] = 99, [Q_KEY_CODE_SHIFT_R] = 110, [Q_KEY_CODE_ALT] = 19, diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 2e41efe1b4..abb377aab9 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -225,7 +225,7 @@ static void pc_init1(MachineState *machine, pc_vga_init(isa_bus, pci_enabled ? pci_bus : NULL); - assert(pcms->vmport != ON_OFF_AUTO_MAX); + assert(pcms->vmport != ON_OFF_AUTO__MAX); if (pcms->vmport == ON_OFF_AUTO_AUTO) { pcms->vmport = xen_enabled() ? ON_OFF_AUTO_OFF : ON_OFF_AUTO_ON; } diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 133bc68fac..9a1206832b 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -233,7 +233,7 @@ static void pc_q35_init(MachineState *machine) pc_register_ferr_irq(gsi[13]); - assert(pcms->vmport != ON_OFF_AUTO_MAX); + assert(pcms->vmport != ON_OFF_AUTO__MAX); if (pcms->vmport == ON_OFF_AUTO_AUTO) { pcms->vmport = xen_enabled() ? ON_OFF_AUTO_OFF : ON_OFF_AUTO_ON; } diff --git a/hw/input/hid.c b/hw/input/hid.c index e39269fc7a..12075c9f65 100644 --- a/hw/input/hid.c +++ b/hw/input/hid.c @@ -108,7 +108,7 @@ void hid_set_next_idle(HIDState *hs) static void hid_pointer_event(DeviceState *dev, QemuConsole *src, InputEvent *evt) { - static const int bmap[INPUT_BUTTON_MAX] = { + static const int bmap[INPUT_BUTTON__MAX] = { [INPUT_BUTTON_LEFT] = 0x01, [INPUT_BUTTON_RIGHT] = 0x02, [INPUT_BUTTON_MIDDLE] = 0x04, diff --git a/hw/input/ps2.c b/hw/input/ps2.c index 3d6d4961db..9096d2167b 100644 --- a/hw/input/ps2.c +++ b/hw/input/ps2.c @@ -382,7 +382,7 @@ static void ps2_mouse_send_packet(PS2MouseState *s) static void ps2_mouse_event(DeviceState *dev, QemuConsole *src, InputEvent *evt) { - static const int bmap[INPUT_BUTTON_MAX] = { + static const int bmap[INPUT_BUTTON__MAX] = { [INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON, [INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON, [INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON, diff --git a/hw/input/virtio-input-hid.c b/hw/input/virtio-input-hid.c index bdd479cd0a..5d00a03b0d 100644 --- a/hw/input/virtio-input-hid.c +++ b/hw/input/virtio-input-hid.c @@ -21,7 +21,7 @@ /* ----------------------------------------------------------------- */ -static const unsigned int keymap_qcode[Q_KEY_CODE_MAX] = { +static const unsigned int keymap_qcode[Q_KEY_CODE__MAX] = { [Q_KEY_CODE_ESC] = KEY_ESC, [Q_KEY_CODE_1] = KEY_1, [Q_KEY_CODE_2] = KEY_2, @@ -138,7 +138,7 @@ static const unsigned int keymap_qcode[Q_KEY_CODE_MAX] = { [Q_KEY_CODE_MENU] = KEY_MENU, }; -static const unsigned int keymap_button[INPUT_BUTTON_MAX] = { +static const unsigned int keymap_button[INPUT_BUTTON__MAX] = { [INPUT_BUTTON_LEFT] = BTN_LEFT, [INPUT_BUTTON_RIGHT] = BTN_RIGHT, [INPUT_BUTTON_MIDDLE] = BTN_MIDDLE, @@ -146,12 +146,12 @@ static const unsigned int keymap_button[INPUT_BUTTON_MAX] = { [INPUT_BUTTON_WHEEL_DOWN] = BTN_GEAR_DOWN, }; -static const unsigned int axismap_rel[INPUT_AXIS_MAX] = { +static const unsigned int axismap_rel[INPUT_AXIS__MAX] = { [INPUT_AXIS_X] = REL_X, [INPUT_AXIS_Y] = REL_Y, }; -static const unsigned int axismap_abs[INPUT_AXIS_MAX] = { +static const unsigned int axismap_abs[INPUT_AXIS__MAX] = { [INPUT_AXIS_X] = ABS_X, [INPUT_AXIS_Y] = ABS_Y, }; diff --git a/include/migration/migration.h b/include/migration/migration.h index fd018b74a2..d9494b895e 100644 --- a/include/migration/migration.h +++ b/include/migration/migration.h @@ -133,7 +133,7 @@ struct MigrationState QemuThread thread; QEMUBH *cleanup_bh; QEMUFile *file; - int parameters[MIGRATION_PARAMETER_MAX]; + int parameters[MIGRATION_PARAMETER__MAX]; int state; MigrationParams params; @@ -151,7 +151,7 @@ struct MigrationState int64_t expected_downtime; int64_t dirty_pages_rate; int64_t dirty_bytes_rate; - bool enabled_capabilities[MIGRATION_CAPABILITY_MAX]; + bool enabled_capabilities[MIGRATION_CAPABILITY__MAX]; int64_t xbzrle_cache_size; int64_t setup_time; int64_t dirty_sync_count; diff --git a/migration/migration.c b/migration/migration.c index adc6b6f1c9..c842499575 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -202,7 +202,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, RUN_STATE_MAX, + r = qapi_enum_parse(RunState_lookup, runstate, RUN_STATE__MAX, -1, &local_err); if (r == -1) { @@ -479,7 +479,7 @@ MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp) int i; caps = NULL; /* silence compiler warning */ - for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) { + for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) { if (head == NULL) { head = g_malloc0(sizeof(*caps)); caps = head; diff --git a/monitor.c b/monitor.c index 9a35d7265f..5546f8abc9 100644 --- a/monitor.c +++ b/monitor.c @@ -441,7 +441,7 @@ static void monitor_protocol_emitter(Monitor *mon, QObject *data, } -static MonitorQAPIEventConf monitor_qapi_event_conf[QAPI_EVENT_MAX] = { +static MonitorQAPIEventConf monitor_qapi_event_conf[QAPI_EVENT__MAX] = { /* Limit guest-triggerable events to 1 per second */ [QAPI_EVENT_RTC_CHANGE] = { 1000 * SCALE_MS }, [QAPI_EVENT_WATCHDOG] = { 1000 * SCALE_MS }, @@ -481,7 +481,7 @@ monitor_qapi_event_queue(QAPIEvent event, QDict *qdict, Error **errp) MonitorQAPIEventConf *evconf; MonitorQAPIEventState *evstate; - assert(event < QAPI_EVENT_MAX); + assert(event < QAPI_EVENT__MAX); evconf = &monitor_qapi_event_conf[event]; trace_monitor_protocol_event_queue(event, qdict, evconf->rate); @@ -946,7 +946,7 @@ EventInfoList *qmp_query_events(Error **errp) EventInfoList *info, *ev_list = NULL; QAPIEvent e; - for (e = 0 ; e < QAPI_EVENT_MAX ; e++) { + for (e = 0 ; e < QAPI_EVENT__MAX ; e++) { const char *event_name = QAPIEvent_lookup[e]; assert(event_name != NULL); info = g_malloc0(sizeof(*info)); @@ -1386,7 +1386,7 @@ static void hmp_mouse_move(Monitor *mon, const QDict *qdict) static void hmp_mouse_button(Monitor *mon, const QDict *qdict) { - static uint32_t bmap[INPUT_BUTTON_MAX] = { + static uint32_t bmap[INPUT_BUTTON__MAX] = { [INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON, [INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON, [INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON, @@ -3217,7 +3217,7 @@ void sendkey_completion(ReadLineState *rs, int nb_args, const char *str) } len = strlen(str); readline_set_completion_index(rs, len); - for (i = 0; i < Q_KEY_CODE_MAX; i++) { + for (i = 0; i < Q_KEY_CODE__MAX; i++) { if (!strncmp(str, QKeyCode_lookup[i], len)) { readline_add_completion(rs, QKeyCode_lookup[i]); } @@ -3316,7 +3316,7 @@ void migrate_set_capability_completion(ReadLineState *rs, int nb_args, readline_set_completion_index(rs, len); if (nb_args == 2) { int i; - for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) { + for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) { const char *name = MigrationCapability_lookup[i]; if (!strncmp(str, name, len)) { readline_add_completion(rs, name); @@ -3337,7 +3337,7 @@ void migrate_set_parameter_completion(ReadLineState *rs, int nb_args, readline_set_completion_index(rs, len); if (nb_args == 2) { int i; - for (i = 0; i < MIGRATION_PARAMETER_MAX; i++) { + for (i = 0; i < MIGRATION_PARAMETER__MAX; i++) { const char *name = MigrationParameter_lookup[i]; if (!strncmp(str, name, len)) { readline_add_completion(rs, name); diff --git a/net/net.c b/net/net.c index ade6051846..87dd3568dc 100644 --- a/net/net.c +++ b/net/net.c @@ -943,7 +943,7 @@ static int net_init_nic(const NetClientOptions *opts, const char *name, } -static int (* const net_client_init_fun[NET_CLIENT_OPTIONS_KIND_MAX])( +static int (* const net_client_init_fun[NET_CLIENT_OPTIONS_KIND__MAX])( const NetClientOptions *opts, const char *name, NetClientState *peer, Error **errp) = { @@ -1296,7 +1296,7 @@ void qmp_set_link(const char *name, bool up, Error **errp) int queues, i; queues = qemu_find_net_clients_except(name, ncs, - NET_CLIENT_OPTIONS_KIND_MAX, + NET_CLIENT_OPTIONS_KIND__MAX, MAX_QUEUE_NUM); if (queues == 0) { diff --git a/qemu-nbd.c b/qemu-nbd.c index 3afec76504..65dc30c189 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -487,7 +487,7 @@ int main(int argc, char **argv) detect_zeroes = qapi_enum_parse(BlockdevDetectZeroesOptions_lookup, optarg, - BLOCKDEV_DETECT_ZEROES_OPTIONS_MAX, + BLOCKDEV_DETECT_ZEROES_OPTIONS__MAX, BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF, &local_err); if (local_err) { diff --git a/replay/replay-input.c b/replay/replay-input.c index 98798955a1..bc15f592dc 100644 --- a/replay/replay-input.c +++ b/replay/replay-input.c @@ -61,7 +61,7 @@ void replay_save_input_event(InputEvent *evt) replay_put_dword(evt->u.key->key->u.qcode); replay_put_byte(evt->u.key->down); break; - case KEY_VALUE_KIND_MAX: + case KEY_VALUE_KIND__MAX: /* keep gcc happy */ break; } @@ -78,7 +78,7 @@ void replay_save_input_event(InputEvent *evt) replay_put_dword(evt->u.abs->axis); replay_put_qword(evt->u.abs->value); break; - case INPUT_EVENT_KIND_MAX: + case INPUT_EVENT_KIND__MAX: /* keep gcc happy */ break; } @@ -109,7 +109,7 @@ InputEvent *replay_read_input_event(void) evt.u.key->key->u.qcode = (QKeyCode)replay_get_dword(); evt.u.key->down = replay_get_byte(); break; - case KEY_VALUE_KIND_MAX: + case KEY_VALUE_KIND__MAX: /* keep gcc happy */ break; } @@ -129,7 +129,7 @@ InputEvent *replay_read_input_event(void) evt.u.abs->axis = (InputAxis)replay_get_dword(); evt.u.abs->value = replay_get_qword(); break; - case INPUT_EVENT_KIND_MAX: + case INPUT_EVENT_KIND__MAX: /* keep gcc happy */ break; } diff --git a/scripts/qapi.py b/scripts/qapi.py index 3e5caa8193..9c541e0312 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -918,7 +918,7 @@ class QAPISchemaEnumType(QAPISchemaType): return c_name(self.name) def c_null(self): - return c_enum_const(self.name, (self.values + ['MAX'])[0], + return c_enum_const(self.name, (self.values + ['_MAX'])[0], self.prefix) def json_type(self): @@ -1568,7 +1568,7 @@ const char *const %(c_name)s_lookup[] = { ''', index=index, value=value) - max_index = c_enum_const(name, 'MAX', prefix) + max_index = c_enum_const(name, '_MAX', prefix) ret += mcgen(''' [%(max_index)s] = NULL, }; @@ -1579,7 +1579,7 @@ const char *const %(c_name)s_lookup[] = { def gen_enum(name, values, prefix=None): # append automatically generated _MAX value - enum_values = values + ['MAX'] + enum_values = values + ['_MAX'] ret = mcgen(''' diff --git a/tests/test-qmp-output-visitor.c b/tests/test-qmp-output-visitor.c index 0d0c85989a..4196e66dde 100644 --- a/tests/test-qmp-output-visitor.c +++ b/tests/test-qmp-output-visitor.c @@ -128,7 +128,7 @@ static void test_visitor_out_enum(TestOutputVisitorData *data, QObject *obj; EnumOne i; - for (i = 0; i < ENUM_ONE_MAX; i++) { + for (i = 0; i < ENUM_ONE__MAX; i++) { visit_type_EnumOne(data->ov, &i, "unused", &error_abort); obj = qmp_output_get_qobject(data->qov); @@ -143,7 +143,7 @@ static void test_visitor_out_enum(TestOutputVisitorData *data, static void test_visitor_out_enum_errors(TestOutputVisitorData *data, const void *unused) { - EnumOne i, bad_values[] = { ENUM_ONE_MAX, -1 }; + EnumOne i, bad_values[] = { ENUM_ONE__MAX, -1 }; Error *err; for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) { @@ -247,7 +247,7 @@ static void test_visitor_out_struct_nested(TestOutputVisitorData *data, static void test_visitor_out_struct_errors(TestOutputVisitorData *data, const void *unused) { - EnumOne bad_values[] = { ENUM_ONE_MAX, -1 }; + EnumOne bad_values[] = { ENUM_ONE__MAX, -1 }; UserDefOne u = {0}; UserDefOne *pu = &u; Error *err; diff --git a/tests/test-string-output-visitor.c b/tests/test-string-output-visitor.c index fd5e67be64..95852523b4 100644 --- a/tests/test-string-output-visitor.c +++ b/tests/test-string-output-visitor.c @@ -194,7 +194,7 @@ static void test_visitor_out_enum(TestOutputVisitorData *data, char *str; EnumOne i; - for (i = 0; i < ENUM_ONE_MAX; i++) { + for (i = 0; i < ENUM_ONE__MAX; i++) { char *str_human; visit_type_EnumOne(data->ov, &i, "unused", &err); @@ -217,7 +217,7 @@ static void test_visitor_out_enum(TestOutputVisitorData *data, static void test_visitor_out_enum_errors(TestOutputVisitorData *data, const void *unused) { - EnumOne i, bad_values[] = { ENUM_ONE_MAX, -1 }; + EnumOne i, bad_values[] = { ENUM_ONE__MAX, -1 }; Error *err; for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) { diff --git a/tpm.c b/tpm.c index f2c59d1f71..0a3e3d5032 100644 --- a/tpm.c +++ b/tpm.c @@ -32,7 +32,7 @@ static TPMDriverOps const *be_drivers[TPM_MAX_DRIVERS] = { }; static enum TpmModel tpm_models[TPM_MAX_MODELS] = { - TPM_MODEL_MAX, + TPM_MODEL__MAX, }; int tpm_register_model(enum TpmModel model) @@ -40,7 +40,7 @@ int tpm_register_model(enum TpmModel model) int i; for (i = 0; i < TPM_MAX_MODELS; i++) { - if (tpm_models[i] == TPM_MODEL_MAX) { + if (tpm_models[i] == TPM_MODEL__MAX) { tpm_models[i] = model; return 0; } @@ -272,7 +272,7 @@ static TPMInfo *qmp_query_tpm_inst(TPMBackend *drv) tpo->has_cancel_path = true; } break; - case TPM_TYPE_MAX: + case TPM_TYPE__MAX: break; } @@ -311,7 +311,7 @@ TpmTypeList *qmp_query_tpm_types(Error **errp) unsigned int i = 0; TpmTypeList *head = NULL, *prev = NULL, *cur_item; - for (i = 0; i < TPM_TYPE_MAX; i++) { + for (i = 0; i < TPM_TYPE__MAX; i++) { if (!tpm_driver_find_by_type(i)) { continue; } @@ -335,7 +335,7 @@ TpmModelList *qmp_query_tpm_models(Error **errp) unsigned int i = 0; TpmModelList *head = NULL, *prev = NULL, *cur_item; - for (i = 0; i < TPM_MODEL_MAX; i++) { + for (i = 0; i < TPM_MODEL__MAX; i++) { if (!tpm_model_is_registered(i)) { continue; } diff --git a/ui/cocoa.m b/ui/cocoa.m index d76b942732..7477d5896c 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -733,7 +733,7 @@ QemuCocoaView *cocoaView; */ if ((isMouseGrabbed || [[self window] isKeyWindow]) && (last_buttons != buttons)) { - static uint32_t bmap[INPUT_BUTTON_MAX] = { + static uint32_t bmap[INPUT_BUTTON__MAX] = { [INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON, [INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON, [INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON, diff --git a/ui/console.c b/ui/console.c index 745c354f53..27a2cdc009 100644 --- a/ui/console.c +++ b/ui/console.c @@ -1108,7 +1108,7 @@ void kbd_put_keysym_console(QemuConsole *s, int keysym) } } -static const int qcode_to_keysym[Q_KEY_CODE_MAX] = { +static const int qcode_to_keysym[Q_KEY_CODE__MAX] = { [Q_KEY_CODE_UP] = QEMU_KEY_UP, [Q_KEY_CODE_DOWN] = QEMU_KEY_DOWN, [Q_KEY_CODE_RIGHT] = QEMU_KEY_RIGHT, diff --git a/ui/input-keymap.c b/ui/input-keymap.c index d36be4b60d..63d71d2632 100644 --- a/ui/input-keymap.c +++ b/ui/input-keymap.c @@ -132,7 +132,7 @@ static const int qcode_to_number[] = { [Q_KEY_CODE_RO] = 0x73, [Q_KEY_CODE_KP_COMMA] = 0x7e, - [Q_KEY_CODE_MAX] = 0, + [Q_KEY_CODE__MAX] = 0, }; static int number_to_qcode[0x100]; @@ -154,7 +154,7 @@ int qemu_input_key_number_to_qcode(uint8_t nr) if (first) { int qcode, number; first = false; - for (qcode = 0; qcode < Q_KEY_CODE_MAX; qcode++) { + for (qcode = 0; qcode < Q_KEY_CODE__MAX; qcode++) { number = qcode_to_number[qcode]; assert(number < ARRAY_SIZE(number_to_qcode)); number_to_qcode[number] = qcode; diff --git a/ui/input-legacy.c b/ui/input-legacy.c index e0a39f08a5..3bc29bd57b 100644 --- a/ui/input-legacy.c +++ b/ui/input-legacy.c @@ -38,7 +38,7 @@ struct QEMUPutMouseEntry { /* new input core */ QemuInputHandler h; QemuInputHandlerState *s; - int axis[INPUT_AXIS_MAX]; + int axis[INPUT_AXIS__MAX]; int buttons; }; @@ -67,7 +67,7 @@ int index_from_key(const char *key) } } - /* Return Q_KEY_CODE_MAX if the key is invalid */ + /* Return Q_KEY_CODE__MAX if the key is invalid */ return i; } @@ -143,7 +143,7 @@ QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque) static void legacy_mouse_event(DeviceState *dev, QemuConsole *src, InputEvent *evt) { - static const int bmap[INPUT_BUTTON_MAX] = { + static const int bmap[INPUT_BUTTON__MAX] = { [INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON, [INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON, [INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON, diff --git a/ui/input.c b/ui/input.c index a0f9873f59..006667b3d5 100644 --- a/ui/input.c +++ b/ui/input.c @@ -211,7 +211,7 @@ static void qemu_input_event_trace(QemuConsole *src, InputEvent *evt) name = QKeyCode_lookup[evt->u.key->key->u.qcode]; trace_input_event_key_qcode(idx, name, evt->u.key->down); break; - case KEY_VALUE_KIND_MAX: + case KEY_VALUE_KIND__MAX: /* keep gcc happy */ break; } @@ -228,7 +228,7 @@ static void qemu_input_event_trace(QemuConsole *src, InputEvent *evt) name = InputAxis_lookup[evt->u.abs->axis]; trace_input_event_abs(idx, name, evt->u.abs->value); break; - case INPUT_EVENT_KIND_MAX: + case INPUT_EVENT_KIND__MAX: /* keep gcc happy */ break; } @@ -430,7 +430,7 @@ void qemu_input_update_buttons(QemuConsole *src, uint32_t *button_map, InputButton btn; uint32_t mask; - for (btn = 0; btn < INPUT_BUTTON_MAX; btn++) { + for (btn = 0; btn < INPUT_BUTTON__MAX; btn++) { mask = button_map[btn]; if ((button_old & mask) == (button_new & mask)) { continue; diff --git a/ui/sdl.c b/ui/sdl.c index 570cb99f08..f4aa0f2567 100644 --- a/ui/sdl.c +++ b/ui/sdl.c @@ -465,7 +465,7 @@ static void sdl_mouse_mode_change(Notifier *notify, void *data) static void sdl_send_mouse_event(int dx, int dy, int x, int y, int state) { - static uint32_t bmap[INPUT_BUTTON_MAX] = { + static uint32_t bmap[INPUT_BUTTON__MAX] = { [INPUT_BUTTON_LEFT] = SDL_BUTTON(SDL_BUTTON_LEFT), [INPUT_BUTTON_MIDDLE] = SDL_BUTTON(SDL_BUTTON_MIDDLE), [INPUT_BUTTON_RIGHT] = SDL_BUTTON(SDL_BUTTON_RIGHT), diff --git a/ui/sdl2.c b/ui/sdl2.c index 5cb75aa364..4be992a195 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -256,7 +256,7 @@ static void sdl_mouse_mode_change(Notifier *notify, void *data) static void sdl_send_mouse_event(struct sdl2_console *scon, int dx, int dy, int x, int y, int state) { - static uint32_t bmap[INPUT_BUTTON_MAX] = { + static uint32_t bmap[INPUT_BUTTON__MAX] = { [INPUT_BUTTON_LEFT] = SDL_BUTTON(SDL_BUTTON_LEFT), [INPUT_BUTTON_MIDDLE] = SDL_BUTTON(SDL_BUTTON_MIDDLE), [INPUT_BUTTON_RIGHT] = SDL_BUTTON(SDL_BUTTON_RIGHT), diff --git a/ui/spice-input.c b/ui/spice-input.c index c342e0dcfb..96f19aac3e 100644 --- a/ui/spice-input.c +++ b/ui/spice-input.c @@ -107,7 +107,7 @@ typedef struct QemuSpicePointer { static void spice_update_buttons(QemuSpicePointer *pointer, int wheel, uint32_t button_mask) { - static uint32_t bmap[INPUT_BUTTON_MAX] = { + static uint32_t bmap[INPUT_BUTTON__MAX] = { [INPUT_BUTTON_LEFT] = 0x01, [INPUT_BUTTON_MIDDLE] = 0x04, [INPUT_BUTTON_RIGHT] = 0x02, diff --git a/ui/vnc.c b/ui/vnc.c index cbe4d3395c..fe7ff26abf 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -1676,7 +1676,7 @@ static void check_pointer_type_change(Notifier *notifier, void *data) static void pointer_event(VncState *vs, int button_mask, int x, int y) { - static uint32_t bmap[INPUT_BUTTON_MAX] = { + static uint32_t bmap[INPUT_BUTTON__MAX] = { [INPUT_BUTTON_LEFT] = 0x01, [INPUT_BUTTON_MIDDLE] = 0x02, [INPUT_BUTTON_RIGHT] = 0x04, diff --git a/vl.c b/vl.c index 4211ff1ffd..5aaea77b0a 100644 --- a/vl.c +++ b/vl.c @@ -570,8 +570,8 @@ static int default_driver_check(void *opaque, QemuOpts *opts, Error **errp) static RunState current_run_state = RUN_STATE_PRELAUNCH; -/* We use RUN_STATE_MAX but any invalid value will do */ -static RunState vmstop_requested = RUN_STATE_MAX; +/* We use RUN_STATE__MAX but any invalid value will do */ +static RunState vmstop_requested = RUN_STATE__MAX; static QemuMutex vmstop_lock; typedef struct { @@ -642,10 +642,10 @@ static const RunStateTransition runstate_transitions_def[] = { { RUN_STATE_GUEST_PANICKED, RUN_STATE_RUNNING }, { RUN_STATE_GUEST_PANICKED, RUN_STATE_FINISH_MIGRATE }, - { RUN_STATE_MAX, RUN_STATE_MAX }, + { RUN_STATE__MAX, RUN_STATE__MAX }, }; -static bool runstate_valid_transitions[RUN_STATE_MAX][RUN_STATE_MAX]; +static bool runstate_valid_transitions[RUN_STATE__MAX][RUN_STATE__MAX]; bool runstate_check(RunState state) { @@ -669,7 +669,7 @@ static void runstate_init(void) const RunStateTransition *p; memset(&runstate_valid_transitions, 0, sizeof(runstate_valid_transitions)); - for (p = &runstate_transitions_def[0]; p->from != RUN_STATE_MAX; p++) { + for (p = &runstate_transitions_def[0]; p->from != RUN_STATE__MAX; p++) { runstate_valid_transitions[p->from][p->to] = true; } @@ -679,7 +679,7 @@ static void runstate_init(void) /* This function will abort() on invalid state transitions */ void runstate_set(RunState new_state) { - assert(new_state < RUN_STATE_MAX); + assert(new_state < RUN_STATE__MAX); if (!runstate_valid_transitions[current_run_state][new_state]) { error_report("invalid runstate transition: '%s' -> '%s'", @@ -717,9 +717,9 @@ static bool qemu_vmstop_requested(RunState *r) { qemu_mutex_lock(&vmstop_lock); *r = vmstop_requested; - vmstop_requested = RUN_STATE_MAX; + vmstop_requested = RUN_STATE__MAX; qemu_mutex_unlock(&vmstop_lock); - return *r < RUN_STATE_MAX; + return *r < RUN_STATE__MAX; } void qemu_system_vmstop_request_prepare(void) @@ -739,7 +739,7 @@ void vm_start(void) RunState requested; qemu_vmstop_requested(&requested); - if (runstate_is_running() && requested == RUN_STATE_MAX) { + if (runstate_is_running() && requested == RUN_STATE__MAX) { return; } -- cgit v1.2.3-55-g7522 From f22a28b898322c01b0463a8b7ec551d72bc61a5b Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Wed, 18 Nov 2015 01:53:00 -0700 Subject: qapi: Add alias for ErrorClass The qapi enum ErrorClass is unusual that it uses 'CamelCase' names, contrary to our documented convention of preferring 'lower-case'. However, this enum is entrenched in the API; we cannot change what strings QMP outputs. Meanwhile, we want to simplify how c_enum_const() is used to generate enum constants, by moving away from the heuristics of camel_to_upper() to a more straightforward c_name(N).upper() - but doing so will rename all of the ErrorClass constants and cause churn to all client files, where the new names are aesthetically less pleasing (ERROR_CLASS_DEVICENOTFOUND looks like we can't make up our minds on whether to break between words). So as always in computer science, solve the problem by some more indirection: rename the qapi type to QapiErrorClass, and add a new enum ErrorClass in error.h whose members are aliases of the qapi type, but with the spelling expected elsewhere in the tree. Then, when c_enum_const() changes the munging, we only have to adjust the one alias spot. Suggested by: Markus Armbruster Signed-off-by: Eric Blake Message-Id: <1447836791-369-26-git-send-email-eblake@redhat.com> Signed-off-by: Markus Armbruster --- include/qapi/error.h | 14 ++++++++++++++ monitor.c | 2 +- qapi/common.json | 5 +++-- qapi/qmp-dispatch.c | 2 +- 4 files changed, 19 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/qapi/error.h b/include/qapi/error.h index 4d42cdc5fd..3060b0c4ea 100644 --- a/include/qapi/error.h +++ b/include/qapi/error.h @@ -90,6 +90,20 @@ */ typedef struct Error Error; +/* + * Overall category of an error. + * Based on the qapi type QapiErrorClass, but reproduced here for nicer + * enum names. + */ +typedef enum ErrorClass { + ERROR_CLASS_GENERIC_ERROR = QAPI_ERROR_CLASS_GENERIC_ERROR, + ERROR_CLASS_COMMAND_NOT_FOUND = QAPI_ERROR_CLASS_COMMAND_NOT_FOUND, + ERROR_CLASS_DEVICE_ENCRYPTED = QAPI_ERROR_CLASS_DEVICE_ENCRYPTED, + ERROR_CLASS_DEVICE_NOT_ACTIVE = QAPI_ERROR_CLASS_DEVICE_NOT_ACTIVE, + ERROR_CLASS_DEVICE_NOT_FOUND = QAPI_ERROR_CLASS_DEVICE_NOT_FOUND, + ERROR_CLASS_KVM_MISSING_CAP = QAPI_ERROR_CLASS_KVM_MISSING_CAP, +} ErrorClass; + /* * Get @err's human-readable error message. */ diff --git a/monitor.c b/monitor.c index 5546f8abc9..289c1181b8 100644 --- a/monitor.c +++ b/monitor.c @@ -403,7 +403,7 @@ static QDict *build_qmp_error_dict(Error *err) QObject *obj; obj = qobject_from_jsonf("{ 'error': { 'class': %s, 'desc': %s } }", - ErrorClass_lookup[error_get_class(err)], + QapiErrorClass_lookup[error_get_class(err)], error_get_pretty(err)); return qobject_to_qdict(obj); diff --git a/qapi/common.json b/qapi/common.json index bad56bf688..6fb40e7a15 100644 --- a/qapi/common.json +++ b/qapi/common.json @@ -3,7 +3,7 @@ # QAPI common definitions ## -# @ErrorClass +# @QapiErrorClass # # QEMU error classes # @@ -24,7 +24,8 @@ # # Since: 1.2 ## -{ 'enum': 'ErrorClass', +{ 'enum': 'QapiErrorClass', + # Keep this in sync with ErrorClass in error.h 'data': [ 'GenericError', 'CommandNotFound', 'DeviceEncrypted', 'DeviceNotActive', 'DeviceNotFound', 'KVMMissingCap' ] } diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c index 7bcc86080e..f36933de64 100644 --- a/qapi/qmp-dispatch.c +++ b/qapi/qmp-dispatch.c @@ -114,7 +114,7 @@ static QObject *do_qmp_dispatch(QObject *request, Error **errp) QObject *qmp_build_error_object(Error *err) { return qobject_from_jsonf("{ 'class': %s, 'desc': %s }", - ErrorClass_lookup[error_get_class(err)], + QapiErrorClass_lookup[error_get_class(err)], error_get_pretty(err)); } -- cgit v1.2.3-55-g7522 From d20a580bc0eac9d489884f6d2ed28105880532b6 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Wed, 18 Nov 2015 01:53:01 -0700 Subject: qapi: Change munging of CamelCase enum values When munging enum values, the fact that we were passing the entire prefix + value through camel_to_upper() meant that enum values spelled with CamelCase could be turned into CAMEL_CASE. However, this provides a potential collision (both OneTwo and One-Two would munge into ONE_TWO) for enum types, when the same two names are valid side-by-side as QAPI member names. By changing the generation of enum constants to always be prefix + '_' + c_name(value, False).upper(), and ensuring that there are no case collisions (in the next patches), we no longer have to worry about names that would be distinct as QAPI members but collide as variant tag names, without having to think about what munging the heuristics in camel_to_upper() will actually perform on an enum value. Making the change will affect enums that did not follow coding conventions, using 'CamelCase' rather than desired 'lower-case'. Thankfully, there are only two culprits: InputButton and ErrorClass. We already tweaked ErrorClass to make it an alias of QapiErrorClass, where only the alias needs changing rather than the whole tree. So the bulk of this change is modifying INPUT_BUTTON_WHEEL_UP to the new INPUT_BUTTON_WHEELUP (and likewise for WHEELDOWN). That part of this commit may later need reverting if we rename the enum constants from 'WheelUp' to 'wheel-up' as part of moving x-input-send-event to a stable interface; but at least we have documentation bread crumbs in place to remind us (commit 513e7cd), and it matches the fact that SDL constants are also spelled SDL_BUTTON_WHEELUP. Suggested by: Markus Armbruster Signed-off-by: Eric Blake Message-Id: <1447836791-369-27-git-send-email-eblake@redhat.com> [Commit message tweaked] Signed-off-by: Markus Armbruster --- hw/input/hid.c | 4 ++-- hw/input/ps2.c | 4 ++-- hw/input/virtio-input-hid.c | 4 ++-- include/qapi/error.h | 12 ++++++------ monitor.c | 2 +- scripts/qapi.py | 2 +- ui/cocoa.m | 4 ++-- ui/gtk.c | 4 ++-- ui/input-legacy.c | 4 ++-- ui/sdl.c | 4 ++-- ui/sdl2.c | 4 ++-- ui/spice-input.c | 4 ++-- ui/vnc.c | 4 ++-- 13 files changed, 28 insertions(+), 28 deletions(-) (limited to 'include') diff --git a/hw/input/hid.c b/hw/input/hid.c index 12075c9f65..3221d2932b 100644 --- a/hw/input/hid.c +++ b/hw/input/hid.c @@ -139,9 +139,9 @@ static void hid_pointer_event(DeviceState *dev, QemuConsole *src, case INPUT_EVENT_KIND_BTN: if (evt->u.btn->down) { e->buttons_state |= bmap[evt->u.btn->button]; - if (evt->u.btn->button == INPUT_BUTTON_WHEEL_UP) { + if (evt->u.btn->button == INPUT_BUTTON_WHEELUP) { e->dz--; - } else if (evt->u.btn->button == INPUT_BUTTON_WHEEL_DOWN) { + } else if (evt->u.btn->button == INPUT_BUTTON_WHEELDOWN) { e->dz++; } } else { diff --git a/hw/input/ps2.c b/hw/input/ps2.c index 9096d2167b..79754cd35a 100644 --- a/hw/input/ps2.c +++ b/hw/input/ps2.c @@ -405,9 +405,9 @@ static void ps2_mouse_event(DeviceState *dev, QemuConsole *src, case INPUT_EVENT_KIND_BTN: if (evt->u.btn->down) { s->mouse_buttons |= bmap[evt->u.btn->button]; - if (evt->u.btn->button == INPUT_BUTTON_WHEEL_UP) { + if (evt->u.btn->button == INPUT_BUTTON_WHEELUP) { s->mouse_dz--; - } else if (evt->u.btn->button == INPUT_BUTTON_WHEEL_DOWN) { + } else if (evt->u.btn->button == INPUT_BUTTON_WHEELDOWN) { s->mouse_dz++; } } else { diff --git a/hw/input/virtio-input-hid.c b/hw/input/virtio-input-hid.c index 5d00a03b0d..a78d11c041 100644 --- a/hw/input/virtio-input-hid.c +++ b/hw/input/virtio-input-hid.c @@ -142,8 +142,8 @@ static const unsigned int keymap_button[INPUT_BUTTON__MAX] = { [INPUT_BUTTON_LEFT] = BTN_LEFT, [INPUT_BUTTON_RIGHT] = BTN_RIGHT, [INPUT_BUTTON_MIDDLE] = BTN_MIDDLE, - [INPUT_BUTTON_WHEEL_UP] = BTN_GEAR_UP, - [INPUT_BUTTON_WHEEL_DOWN] = BTN_GEAR_DOWN, + [INPUT_BUTTON_WHEELUP] = BTN_GEAR_UP, + [INPUT_BUTTON_WHEELDOWN] = BTN_GEAR_DOWN, }; static const unsigned int axismap_rel[INPUT_AXIS__MAX] = { diff --git a/include/qapi/error.h b/include/qapi/error.h index 3060b0c4ea..6285cf50d1 100644 --- a/include/qapi/error.h +++ b/include/qapi/error.h @@ -96,12 +96,12 @@ typedef struct Error Error; * enum names. */ typedef enum ErrorClass { - ERROR_CLASS_GENERIC_ERROR = QAPI_ERROR_CLASS_GENERIC_ERROR, - ERROR_CLASS_COMMAND_NOT_FOUND = QAPI_ERROR_CLASS_COMMAND_NOT_FOUND, - ERROR_CLASS_DEVICE_ENCRYPTED = QAPI_ERROR_CLASS_DEVICE_ENCRYPTED, - ERROR_CLASS_DEVICE_NOT_ACTIVE = QAPI_ERROR_CLASS_DEVICE_NOT_ACTIVE, - ERROR_CLASS_DEVICE_NOT_FOUND = QAPI_ERROR_CLASS_DEVICE_NOT_FOUND, - ERROR_CLASS_KVM_MISSING_CAP = QAPI_ERROR_CLASS_KVM_MISSING_CAP, + ERROR_CLASS_GENERIC_ERROR = QAPI_ERROR_CLASS_GENERICERROR, + ERROR_CLASS_COMMAND_NOT_FOUND = QAPI_ERROR_CLASS_COMMANDNOTFOUND, + ERROR_CLASS_DEVICE_ENCRYPTED = QAPI_ERROR_CLASS_DEVICEENCRYPTED, + ERROR_CLASS_DEVICE_NOT_ACTIVE = QAPI_ERROR_CLASS_DEVICENOTACTIVE, + ERROR_CLASS_DEVICE_NOT_FOUND = QAPI_ERROR_CLASS_DEVICENOTFOUND, + ERROR_CLASS_KVM_MISSING_CAP = QAPI_ERROR_CLASS_KVMMISSINGCAP, } ErrorClass; /* diff --git a/monitor.c b/monitor.c index 289c1181b8..e7e7ae2c5e 100644 --- a/monitor.c +++ b/monitor.c @@ -1375,7 +1375,7 @@ static void hmp_mouse_move(Monitor *mon, const QDict *qdict) if (dz_str) { dz = strtol(dz_str, NULL, 0); if (dz != 0) { - button = (dz > 0) ? INPUT_BUTTON_WHEEL_UP : INPUT_BUTTON_WHEEL_DOWN; + button = (dz > 0) ? INPUT_BUTTON_WHEELUP : INPUT_BUTTON_WHEELDOWN; qemu_input_queue_btn(NULL, button, true); qemu_input_event_sync(); qemu_input_queue_btn(NULL, button, false); diff --git a/scripts/qapi.py b/scripts/qapi.py index 6acef1f5f3..10fcfbc8d2 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -1440,7 +1440,7 @@ def camel_to_upper(value): def c_enum_const(type_name, const_name, prefix=None): if prefix is not None: type_name = prefix - return camel_to_upper(type_name + '_' + const_name) + return camel_to_upper(type_name) + '_' + c_name(const_name, False).upper() c_name_trans = string.maketrans('.-', '__') diff --git a/ui/cocoa.m b/ui/cocoa.m index 7477d5896c..d866f23ec3 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -737,8 +737,8 @@ QemuCocoaView *cocoaView; [INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON, [INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON, [INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON, - [INPUT_BUTTON_WHEEL_UP] = MOUSE_EVENT_WHEELUP, - [INPUT_BUTTON_WHEEL_DOWN] = MOUSE_EVENT_WHEELDN, + [INPUT_BUTTON_WHEELUP] = MOUSE_EVENT_WHEELUP, + [INPUT_BUTTON_WHEELDOWN] = MOUSE_EVENT_WHEELDN, }; qemu_input_update_buttons(dcl->con, bmap, last_buttons, buttons); last_buttons = buttons; diff --git a/ui/gtk.c b/ui/gtk.c index 47b37e1f14..40e78c59c0 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -965,9 +965,9 @@ static gboolean gd_scroll_event(GtkWidget *widget, GdkEventScroll *scroll, InputButton btn; if (scroll->direction == GDK_SCROLL_UP) { - btn = INPUT_BUTTON_WHEEL_UP; + btn = INPUT_BUTTON_WHEELUP; } else if (scroll->direction == GDK_SCROLL_DOWN) { - btn = INPUT_BUTTON_WHEEL_DOWN; + btn = INPUT_BUTTON_WHEELDOWN; } else { return TRUE; } diff --git a/ui/input-legacy.c b/ui/input-legacy.c index 3bc29bd57b..35dfc27687 100644 --- a/ui/input-legacy.c +++ b/ui/input-legacy.c @@ -157,7 +157,7 @@ static void legacy_mouse_event(DeviceState *dev, QemuConsole *src, } else { s->buttons &= ~bmap[evt->u.btn->button]; } - if (evt->u.btn->down && evt->u.btn->button == INPUT_BUTTON_WHEEL_UP) { + if (evt->u.btn->down && evt->u.btn->button == INPUT_BUTTON_WHEELUP) { s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque, s->axis[INPUT_AXIS_X], s->axis[INPUT_AXIS_Y], @@ -165,7 +165,7 @@ static void legacy_mouse_event(DeviceState *dev, QemuConsole *src, s->buttons); } if (evt->u.btn->down && - evt->u.btn->button == INPUT_BUTTON_WHEEL_DOWN) { + evt->u.btn->button == INPUT_BUTTON_WHEELDOWN) { s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque, s->axis[INPUT_AXIS_X], s->axis[INPUT_AXIS_Y], diff --git a/ui/sdl.c b/ui/sdl.c index f4aa0f2567..c837436096 100644 --- a/ui/sdl.c +++ b/ui/sdl.c @@ -469,8 +469,8 @@ static void sdl_send_mouse_event(int dx, int dy, int x, int y, int state) [INPUT_BUTTON_LEFT] = SDL_BUTTON(SDL_BUTTON_LEFT), [INPUT_BUTTON_MIDDLE] = SDL_BUTTON(SDL_BUTTON_MIDDLE), [INPUT_BUTTON_RIGHT] = SDL_BUTTON(SDL_BUTTON_RIGHT), - [INPUT_BUTTON_WHEEL_UP] = SDL_BUTTON(SDL_BUTTON_WHEELUP), - [INPUT_BUTTON_WHEEL_DOWN] = SDL_BUTTON(SDL_BUTTON_WHEELDOWN), + [INPUT_BUTTON_WHEELUP] = SDL_BUTTON(SDL_BUTTON_WHEELUP), + [INPUT_BUTTON_WHEELDOWN] = SDL_BUTTON(SDL_BUTTON_WHEELDOWN), }; static uint32_t prev_state; diff --git a/ui/sdl2.c b/ui/sdl2.c index 4be992a195..cf38df2684 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -504,9 +504,9 @@ static void handle_mousewheel(SDL_Event *ev) InputButton btn; if (wev->y > 0) { - btn = INPUT_BUTTON_WHEEL_UP; + btn = INPUT_BUTTON_WHEELUP; } else if (wev->y < 0) { - btn = INPUT_BUTTON_WHEEL_DOWN; + btn = INPUT_BUTTON_WHEELDOWN; } else { return; } diff --git a/ui/spice-input.c b/ui/spice-input.c index 96f19aac3e..2b3b9ed714 100644 --- a/ui/spice-input.c +++ b/ui/spice-input.c @@ -111,8 +111,8 @@ static void spice_update_buttons(QemuSpicePointer *pointer, [INPUT_BUTTON_LEFT] = 0x01, [INPUT_BUTTON_MIDDLE] = 0x04, [INPUT_BUTTON_RIGHT] = 0x02, - [INPUT_BUTTON_WHEEL_UP] = 0x10, - [INPUT_BUTTON_WHEEL_DOWN] = 0x20, + [INPUT_BUTTON_WHEELUP] = 0x10, + [INPUT_BUTTON_WHEELDOWN] = 0x20, }; if (wheel < 0) { diff --git a/ui/vnc.c b/ui/vnc.c index fe7ff26abf..b9c57fff05 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -1680,8 +1680,8 @@ static void pointer_event(VncState *vs, int button_mask, int x, int y) [INPUT_BUTTON_LEFT] = 0x01, [INPUT_BUTTON_MIDDLE] = 0x02, [INPUT_BUTTON_RIGHT] = 0x04, - [INPUT_BUTTON_WHEEL_UP] = 0x08, - [INPUT_BUTTON_WHEEL_DOWN] = 0x10, + [INPUT_BUTTON_WHEELUP] = 0x08, + [INPUT_BUTTON_WHEELDOWN] = 0x10, }; QemuConsole *con = vs->vd->dcl.con; int width = pixman_image_get_width(vs->vd->server); -- cgit v1.2.3-55-g7522 From 55e1819c509b3d9c10a54678b9c585bbda13889e Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Tue, 1 Dec 2015 22:20:45 -0700 Subject: qobject: Simplify QObject The QObject hierarchy is small enough, and unlikely to grow further (since we only use it to map to JSON and already cover all JSON types), that we can simplify things by not tracking a separate vtable, but just inline the code element of the vtable QType directly into QObject (renamed to type), and track a separate array of destroy functions. We can drop qnull_destroy_obj() in the process. The remaining QObject subclasses must export their destructor. This also has the nice benefit of moving the typename 'QType' out of the way, so that the next patch can repurpose it for a nicer name for 'qtype_code'. The various objects are still the same size (so no change in cache line pressure), but now have less indirection (although I didn't bother benchmarking to see if there is a noticeable speedup, as we don't have hard evidence that this was in a performance hotspot in the first place). A future patch could drop the refcnt size to 32 bits for a smaller struct on 64-bit architectures, if desired (we have limits on the largest JSON that we are willing to parse, and will probably never need to take full advantage of a 64-bit refcnt). Suggested-by: Markus Armbruster Signed-off-by: Eric Blake Message-Id: <1449033659-25497-2-git-send-email-eblake@redhat.com> Signed-off-by: Markus Armbruster --- include/qapi/qmp/qbool.h | 1 + include/qapi/qmp/qdict.h | 1 + include/qapi/qmp/qfloat.h | 1 + include/qapi/qmp/qint.h | 1 + include/qapi/qmp/qlist.h | 1 + include/qapi/qmp/qobject.h | 31 +++++++++++++++---------------- include/qapi/qmp/qstring.h | 1 + qobject/Makefile.objs | 2 +- qobject/qbool.c | 11 ++--------- qobject/qdict.c | 11 ++--------- qobject/qfloat.c | 11 ++--------- qobject/qint.c | 11 ++--------- qobject/qlist.c | 11 ++--------- qobject/qnull.c | 12 +----------- qobject/qobject.c | 34 ++++++++++++++++++++++++++++++++++ qobject/qstring.c | 11 ++--------- 16 files changed, 69 insertions(+), 82 deletions(-) create mode 100644 qobject/qobject.c (limited to 'include') diff --git a/include/qapi/qmp/qbool.h b/include/qapi/qmp/qbool.h index d9256e4268..836d078866 100644 --- a/include/qapi/qmp/qbool.h +++ b/include/qapi/qmp/qbool.h @@ -25,5 +25,6 @@ typedef struct QBool { QBool *qbool_from_bool(bool value); bool qbool_get_bool(const QBool *qb); QBool *qobject_to_qbool(const QObject *obj); +void qbool_destroy_obj(QObject *obj); #endif /* QBOOL_H */ diff --git a/include/qapi/qmp/qdict.h b/include/qapi/qmp/qdict.h index 787c658967..6c2a0e501e 100644 --- a/include/qapi/qmp/qdict.h +++ b/include/qapi/qmp/qdict.h @@ -48,6 +48,7 @@ void qdict_iter(const QDict *qdict, void *opaque); const QDictEntry *qdict_first(const QDict *qdict); const QDictEntry *qdict_next(const QDict *qdict, const QDictEntry *entry); +void qdict_destroy_obj(QObject *obj); /* Helper to qdict_put_obj(), accepts any object */ #define qdict_put(qdict, key, obj) \ diff --git a/include/qapi/qmp/qfloat.h b/include/qapi/qmp/qfloat.h index 46745e50d1..a8af2a89b2 100644 --- a/include/qapi/qmp/qfloat.h +++ b/include/qapi/qmp/qfloat.h @@ -25,5 +25,6 @@ typedef struct QFloat { QFloat *qfloat_from_double(double value); double qfloat_get_double(const QFloat *qi); QFloat *qobject_to_qfloat(const QObject *obj); +void qfloat_destroy_obj(QObject *obj); #endif /* QFLOAT_H */ diff --git a/include/qapi/qmp/qint.h b/include/qapi/qmp/qint.h index 339a9abb8f..049e528079 100644 --- a/include/qapi/qmp/qint.h +++ b/include/qapi/qmp/qint.h @@ -24,5 +24,6 @@ typedef struct QInt { QInt *qint_from_int(int64_t value); int64_t qint_get_int(const QInt *qi); QInt *qobject_to_qint(const QObject *obj); +void qint_destroy_obj(QObject *obj); #endif /* QINT_H */ diff --git a/include/qapi/qmp/qlist.h b/include/qapi/qmp/qlist.h index b1bf7852c5..a84117ecb1 100644 --- a/include/qapi/qmp/qlist.h +++ b/include/qapi/qmp/qlist.h @@ -49,6 +49,7 @@ QObject *qlist_peek(QList *qlist); int qlist_empty(const QList *qlist); size_t qlist_size(const QList *qlist); QList *qobject_to_qlist(const QObject *obj); +void qlist_destroy_obj(QObject *obj); static inline const QListEntry *qlist_first(const QList *qlist) { diff --git a/include/qapi/qmp/qobject.h b/include/qapi/qmp/qobject.h index 4b96ed5837..550ba40dde 100644 --- a/include/qapi/qmp/qobject.h +++ b/include/qapi/qmp/qobject.h @@ -47,15 +47,8 @@ typedef enum { QTYPE_MAX, } qtype_code; -struct QObject; - -typedef struct QType { - qtype_code code; - void (*destroy)(struct QObject *); -} QType; - typedef struct QObject { - const QType *type; + qtype_code type; size_t refcnt; } QObject; @@ -71,9 +64,12 @@ typedef struct QObject { qobject_decref(obj ? QOBJECT(obj) : NULL) /* Initialize an object to default values */ -#define QOBJECT_INIT(obj, qtype_type) \ - obj->base.refcnt = 1; \ - obj->base.type = qtype_type +static inline void qobject_init(QObject *obj, qtype_code type) +{ + assert(QTYPE_NONE < type && type < QTYPE_MAX); + obj->refcnt = 1; + obj->type = type; +} /** * qobject_incref(): Increment QObject's reference count @@ -84,6 +80,11 @@ static inline void qobject_incref(QObject *obj) obj->refcnt++; } +/** + * qobject_destroy(): Free resources used by the object + */ +void qobject_destroy(QObject *obj); + /** * qobject_decref(): Decrement QObject's reference count, deallocate * when it reaches zero @@ -92,9 +93,7 @@ static inline void qobject_decref(QObject *obj) { assert(!obj || obj->refcnt); if (obj && --obj->refcnt == 0) { - assert(obj->type != NULL); - assert(obj->type->destroy != NULL); - obj->type->destroy(obj); + qobject_destroy(obj); } } @@ -103,8 +102,8 @@ static inline void qobject_decref(QObject *obj) */ static inline qtype_code qobject_type(const QObject *obj) { - assert(obj->type != NULL); - return obj->type->code; + assert(QTYPE_NONE < obj->type && obj->type < QTYPE_MAX); + return obj->type; } extern QObject qnull_; diff --git a/include/qapi/qmp/qstring.h b/include/qapi/qmp/qstring.h index 34675a7fc0..df7df558b2 100644 --- a/include/qapi/qmp/qstring.h +++ b/include/qapi/qmp/qstring.h @@ -32,5 +32,6 @@ void qstring_append_int(QString *qstring, int64_t value); void qstring_append(QString *qstring, const char *str); void qstring_append_chr(QString *qstring, int c); QString *qobject_to_qstring(const QObject *obj); +void qstring_destroy_obj(QObject *obj); #endif /* QSTRING_H */ diff --git a/qobject/Makefile.objs b/qobject/Makefile.objs index 0031e8b691..bed55084bb 100644 --- a/qobject/Makefile.objs +++ b/qobject/Makefile.objs @@ -1,2 +1,2 @@ util-obj-y = qnull.o qint.o qstring.o qdict.o qlist.o qfloat.o qbool.o -util-obj-y += qjson.o json-lexer.o json-streamer.o json-parser.o +util-obj-y += qjson.o qobject.o json-lexer.o json-streamer.o json-parser.o diff --git a/qobject/qbool.c b/qobject/qbool.c index bc6535fa49..856c743357 100644 --- a/qobject/qbool.c +++ b/qobject/qbool.c @@ -15,13 +15,6 @@ #include "qapi/qmp/qobject.h" #include "qemu-common.h" -static void qbool_destroy_obj(QObject *obj); - -static const QType qbool_type = { - .code = QTYPE_QBOOL, - .destroy = qbool_destroy_obj, -}; - /** * qbool_from_bool(): Create a new QBool from a bool * @@ -32,8 +25,8 @@ QBool *qbool_from_bool(bool value) QBool *qb; qb = g_malloc(sizeof(*qb)); + qobject_init(QOBJECT(qb), QTYPE_QBOOL); qb->value = value; - QOBJECT_INIT(qb, &qbool_type); return qb; } @@ -61,7 +54,7 @@ QBool *qobject_to_qbool(const QObject *obj) * qbool_destroy_obj(): Free all memory allocated by a * QBool object */ -static void qbool_destroy_obj(QObject *obj) +void qbool_destroy_obj(QObject *obj) { assert(obj != NULL); g_free(qobject_to_qbool(obj)); diff --git a/qobject/qdict.c b/qobject/qdict.c index 2d67bf1579..eeade159cc 100644 --- a/qobject/qdict.c +++ b/qobject/qdict.c @@ -19,13 +19,6 @@ #include "qemu/queue.h" #include "qemu-common.h" -static void qdict_destroy_obj(QObject *obj); - -static const QType qdict_type = { - .code = QTYPE_QDICT, - .destroy = qdict_destroy_obj, -}; - /** * qdict_new(): Create a new QDict * @@ -36,7 +29,7 @@ QDict *qdict_new(void) QDict *qdict; qdict = g_malloc0(sizeof(*qdict)); - QOBJECT_INIT(qdict, &qdict_type); + qobject_init(QOBJECT(qdict), QTYPE_QDICT); return qdict; } @@ -441,7 +434,7 @@ void qdict_del(QDict *qdict, const char *key) /** * qdict_destroy_obj(): Free all the memory allocated by a QDict */ -static void qdict_destroy_obj(QObject *obj) +void qdict_destroy_obj(QObject *obj) { int i; QDict *qdict; diff --git a/qobject/qfloat.c b/qobject/qfloat.c index c86516327f..87d89a7721 100644 --- a/qobject/qfloat.c +++ b/qobject/qfloat.c @@ -15,13 +15,6 @@ #include "qapi/qmp/qobject.h" #include "qemu-common.h" -static void qfloat_destroy_obj(QObject *obj); - -static const QType qfloat_type = { - .code = QTYPE_QFLOAT, - .destroy = qfloat_destroy_obj, -}; - /** * qfloat_from_int(): Create a new QFloat from a float * @@ -32,8 +25,8 @@ QFloat *qfloat_from_double(double value) QFloat *qf; qf = g_malloc(sizeof(*qf)); + qobject_init(QOBJECT(qf), QTYPE_QFLOAT); qf->value = value; - QOBJECT_INIT(qf, &qfloat_type); return qf; } @@ -61,7 +54,7 @@ QFloat *qobject_to_qfloat(const QObject *obj) * qfloat_destroy_obj(): Free all memory allocated by a * QFloat object */ -static void qfloat_destroy_obj(QObject *obj) +void qfloat_destroy_obj(QObject *obj) { assert(obj != NULL); g_free(qobject_to_qfloat(obj)); diff --git a/qobject/qint.c b/qobject/qint.c index 999688e9ce..7cba9adf40 100644 --- a/qobject/qint.c +++ b/qobject/qint.c @@ -14,13 +14,6 @@ #include "qapi/qmp/qobject.h" #include "qemu-common.h" -static void qint_destroy_obj(QObject *obj); - -static const QType qint_type = { - .code = QTYPE_QINT, - .destroy = qint_destroy_obj, -}; - /** * qint_from_int(): Create a new QInt from an int64_t * @@ -31,8 +24,8 @@ QInt *qint_from_int(int64_t value) QInt *qi; qi = g_malloc(sizeof(*qi)); + qobject_init(QOBJECT(qi), QTYPE_QINT); qi->value = value; - QOBJECT_INIT(qi, &qint_type); return qi; } @@ -60,7 +53,7 @@ QInt *qobject_to_qint(const QObject *obj) * qint_destroy_obj(): Free all memory allocated by a * QInt object */ -static void qint_destroy_obj(QObject *obj) +void qint_destroy_obj(QObject *obj) { assert(obj != NULL); g_free(qobject_to_qint(obj)); diff --git a/qobject/qlist.c b/qobject/qlist.c index 298003aaf7..3c045aed11 100644 --- a/qobject/qlist.c +++ b/qobject/qlist.c @@ -15,13 +15,6 @@ #include "qemu/queue.h" #include "qemu-common.h" -static void qlist_destroy_obj(QObject *obj); - -static const QType qlist_type = { - .code = QTYPE_QLIST, - .destroy = qlist_destroy_obj, -}; - /** * qlist_new(): Create a new QList * @@ -32,8 +25,8 @@ QList *qlist_new(void) QList *qlist; qlist = g_malloc(sizeof(*qlist)); + qobject_init(QOBJECT(qlist), QTYPE_QLIST); QTAILQ_INIT(&qlist->head); - QOBJECT_INIT(qlist, &qlist_type); return qlist; } @@ -151,7 +144,7 @@ QList *qobject_to_qlist(const QObject *obj) /** * qlist_destroy_obj(): Free all the memory allocated by a QList */ -static void qlist_destroy_obj(QObject *obj) +void qlist_destroy_obj(QObject *obj) { QList *qlist; QListEntry *entry, *next_entry; diff --git a/qobject/qnull.c b/qobject/qnull.c index 9873e266e6..5f7ba4d01a 100644 --- a/qobject/qnull.c +++ b/qobject/qnull.c @@ -13,17 +13,7 @@ #include "qemu-common.h" #include "qapi/qmp/qobject.h" -static void qnull_destroy_obj(QObject *obj) -{ - assert(0); -} - -static const QType qnull_type = { - .code = QTYPE_QNULL, - .destroy = qnull_destroy_obj, -}; - QObject qnull_ = { - .type = &qnull_type, + .type = QTYPE_QNULL, .refcnt = 1, }; diff --git a/qobject/qobject.c b/qobject/qobject.c new file mode 100644 index 0000000000..1df315ab01 --- /dev/null +++ b/qobject/qobject.c @@ -0,0 +1,34 @@ +/* + * QObject + * + * Copyright (C) 2015 Red Hat, Inc. + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 + * or later. See the COPYING.LIB file in the top-level directory. + */ + +#include "qemu-common.h" +#include "qapi/qmp/qbool.h" +#include "qapi/qmp/qdict.h" +#include "qapi/qmp/qfloat.h" +#include "qapi/qmp/qint.h" +#include "qapi/qmp/qlist.h" +#include "qapi/qmp/qstring.h" + +static void (*qdestroy[QTYPE_MAX])(QObject *) = { + [QTYPE_NONE] = NULL, /* No such object exists */ + [QTYPE_QNULL] = NULL, /* qnull_ is indestructible */ + [QTYPE_QINT] = qint_destroy_obj, + [QTYPE_QSTRING] = qstring_destroy_obj, + [QTYPE_QDICT] = qdict_destroy_obj, + [QTYPE_QLIST] = qlist_destroy_obj, + [QTYPE_QFLOAT] = qfloat_destroy_obj, + [QTYPE_QBOOL] = qbool_destroy_obj, +}; + +void qobject_destroy(QObject *obj) +{ + assert(!obj->refcnt); + assert(QTYPE_QNULL < obj->type && obj->type < QTYPE_MAX); + qdestroy[obj->type](obj); +} diff --git a/qobject/qstring.c b/qobject/qstring.c index cb72dfbfc8..f44c5c424d 100644 --- a/qobject/qstring.c +++ b/qobject/qstring.c @@ -14,13 +14,6 @@ #include "qapi/qmp/qstring.h" #include "qemu-common.h" -static void qstring_destroy_obj(QObject *obj); - -static const QType qstring_type = { - .code = QTYPE_QSTRING, - .destroy = qstring_destroy_obj, -}; - /** * qstring_new(): Create a new empty QString * @@ -49,6 +42,7 @@ QString *qstring_from_substr(const char *str, int start, int end) QString *qstring; qstring = g_malloc(sizeof(*qstring)); + qobject_init(QOBJECT(qstring), QTYPE_QSTRING); qstring->length = end - start + 1; qstring->capacity = qstring->length; @@ -57,7 +51,6 @@ QString *qstring_from_substr(const char *str, int start, int end) memcpy(qstring->string, str + start, qstring->length); qstring->string[qstring->length] = 0; - QOBJECT_INIT(qstring, &qstring_type); return qstring; } @@ -138,7 +131,7 @@ const char *qstring_get_str(const QString *qstring) * qstring_destroy_obj(): Free all memory allocated by a QString * object */ -static void qstring_destroy_obj(QObject *obj) +void qstring_destroy_obj(QObject *obj) { QString *qs; -- cgit v1.2.3-55-g7522 From 1310a3d3bd9301ff5a825287638cfab24c2c6689 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Tue, 1 Dec 2015 22:20:46 -0700 Subject: qobject: Rename qtype_code to QType The name QType matches our CODING_STYLE conventions for type names in CamelCase. It also matches the fact that we are already naming all the enum members with a prefix of QTYPE, not QTYPE_CODE. And doing the rename will also make it easier for the next patch to use QAPI for providing the enum, which also wants CamelCase type names. Signed-off-by: Eric Blake Message-Id: <1449033659-25497-3-git-send-email-eblake@redhat.com> Signed-off-by: Markus Armbruster --- block/qapi.c | 4 ++-- include/hw/qdev-core.h | 2 +- include/qapi/qmp/qobject.h | 8 ++++---- qobject/qdict.c | 3 +-- scripts/qapi.py | 2 +- 5 files changed, 9 insertions(+), 10 deletions(-) (limited to 'include') diff --git a/block/qapi.c b/block/qapi.c index 267f147fe3..c0e877e07e 100644 --- a/block/qapi.c +++ b/block/qapi.c @@ -588,7 +588,7 @@ static void dump_qlist(fprintf_function func_fprintf, void *f, int indentation, int i = 0; for (entry = qlist_first(list); entry; entry = qlist_next(entry), i++) { - qtype_code type = qobject_type(entry->value); + QType type = qobject_type(entry->value); bool composite = (type == QTYPE_QDICT || type == QTYPE_QLIST); const char *format = composite ? "%*s[%i]:\n" : "%*s[%i]: "; @@ -606,7 +606,7 @@ static void dump_qdict(fprintf_function func_fprintf, void *f, int indentation, const QDictEntry *entry; for (entry = qdict_first(dict); entry; entry = qdict_next(dict, entry)) { - qtype_code type = qobject_type(entry->value); + QType type = qobject_type(entry->value); bool composite = (type == QTYPE_QDICT || type == QTYPE_QLIST); const char *format = composite ? "%*s%s:\n" : "%*s%s: "; char key[strlen(entry->key) + 1]; diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index c537969f4e..abcdee852b 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -239,7 +239,7 @@ struct Property { PropertyInfo *info; ptrdiff_t offset; uint8_t bitnr; - qtype_code qtype; + QType qtype; int64_t defval; int arrayoffset; PropertyInfo *arrayinfo; diff --git a/include/qapi/qmp/qobject.h b/include/qapi/qmp/qobject.h index 550ba40dde..c0f1e99bca 100644 --- a/include/qapi/qmp/qobject.h +++ b/include/qapi/qmp/qobject.h @@ -45,10 +45,10 @@ typedef enum { QTYPE_QFLOAT, QTYPE_QBOOL, QTYPE_MAX, -} qtype_code; +} QType; typedef struct QObject { - qtype_code type; + QType type; size_t refcnt; } QObject; @@ -64,7 +64,7 @@ typedef struct QObject { qobject_decref(obj ? QOBJECT(obj) : NULL) /* Initialize an object to default values */ -static inline void qobject_init(QObject *obj, qtype_code type) +static inline void qobject_init(QObject *obj, QType type) { assert(QTYPE_NONE < type && type < QTYPE_MAX); obj->refcnt = 1; @@ -100,7 +100,7 @@ static inline void qobject_decref(QObject *obj) /** * qobject_type(): Return the QObject's type */ -static inline qtype_code qobject_type(const QObject *obj) +static inline QType qobject_type(const QObject *obj) { assert(QTYPE_NONE < obj->type && obj->type < QTYPE_MAX); return obj->type; diff --git a/qobject/qdict.c b/qobject/qdict.c index eeade159cc..19df837c55 100644 --- a/qobject/qdict.c +++ b/qobject/qdict.c @@ -177,8 +177,7 @@ size_t qdict_size(const QDict *qdict) /** * qdict_get_obj(): Get a QObject of a specific type */ -static QObject *qdict_get_obj(const QDict *qdict, const char *key, - qtype_code type) +static QObject *qdict_get_obj(const QDict *qdict, const char *key, QType type) { QObject *obj; diff --git a/scripts/qapi.py b/scripts/qapi.py index 10fcfbc8d2..b336fbd57c 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -33,7 +33,7 @@ builtin_types = { 'uint32': 'QTYPE_QINT', 'uint64': 'QTYPE_QINT', 'size': 'QTYPE_QINT', - 'any': None, # any qtype_code possible, actually + 'any': None, # any QType possible, actually } # Whitelist of commands allowed to return a non-dictionary -- cgit v1.2.3-55-g7522 From 7264f5c50cc1be0f1406e3ebb45aedcca02f603a Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Tue, 1 Dec 2015 22:20:47 -0700 Subject: qapi: Convert QType into QAPI built-in enum type What's more meta than using qapi to define qapi? :) Convert QType into a full-fledged[*] builtin qapi enum type, so that a subsequent patch can then use it as the discriminator type of qapi alternate types. Fortunately, the judicious use of 'prefix' in the qapi definition avoids churn to the spelling of the enum constants. To avoid circular definitions, we have to flip the order of inclusion between "qobject.h" vs. "qapi-types.h". Back in commit 28770e0, we had the latter include the former, so that we could use 'QObject *' for our implementation of 'any'. But that usage also works with only a forward declaration, whereas the definition of QObject requires QType to be a complete type. [*] The type has to be builtin, rather than declared in qapi/common.json, because we want to use it for alternates even when common.json is not included. But since it is the first builtin enum type, we have to add special cases to qapi-types and qapi-visit to only emit definitions once, even when two qapi files are being compiled into the same binary (the way we already handled builtin list types like 'intList'). We may need to revisit how multiple qapi files share common types, but that's a project for another day. Signed-off-by: Eric Blake Message-Id: <1449033659-25497-4-git-send-email-eblake@redhat.com> Signed-off-by: Markus Armbruster --- docs/qapi-code-gen.txt | 1 + include/qapi/qmp/qobject.h | 21 +++++---------------- include/qemu/typedefs.h | 1 + qobject/qobject.c | 4 ++-- scripts/qapi-types.py | 16 ++++++++++++---- scripts/qapi-visit.py | 11 +++++++++-- scripts/qapi.py | 6 ++++++ tests/qapi-schema/alternate-empty.out | 2 ++ tests/qapi-schema/comments.out | 2 ++ tests/qapi-schema/empty.out | 2 ++ tests/qapi-schema/event-case.out | 2 ++ tests/qapi-schema/flat-union-empty.out | 2 ++ tests/qapi-schema/ident-with-escape.out | 2 ++ tests/qapi-schema/include-relpath.out | 2 ++ tests/qapi-schema/include-repetition.out | 2 ++ tests/qapi-schema/include-simple.out | 2 ++ tests/qapi-schema/indented-expr.out | 2 ++ tests/qapi-schema/qapi-schema-test.out | 2 ++ tests/qapi-schema/union-clash-data.out | 2 ++ tests/qapi-schema/union-empty.out | 2 ++ 20 files changed, 62 insertions(+), 24 deletions(-) (limited to 'include') diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt index 2becba95b9..79bf072695 100644 --- a/docs/qapi-code-gen.txt +++ b/docs/qapi-code-gen.txt @@ -160,6 +160,7 @@ The following types are predefined, and map to C as follows: accepts size suffixes bool bool JSON true or false any QObject * any JSON value + QType QType JSON string matching enum QType values === Includes === diff --git a/include/qapi/qmp/qobject.h b/include/qapi/qmp/qobject.h index c0f1e99bca..74459ae14b 100644 --- a/include/qapi/qmp/qobject.h +++ b/include/qapi/qmp/qobject.h @@ -34,23 +34,12 @@ #include #include +#include "qapi-types.h" -typedef enum { - QTYPE_NONE, /* sentinel value, no QObject has this type code */ - QTYPE_QNULL, - QTYPE_QINT, - QTYPE_QSTRING, - QTYPE_QDICT, - QTYPE_QLIST, - QTYPE_QFLOAT, - QTYPE_QBOOL, - QTYPE_MAX, -} QType; - -typedef struct QObject { +struct QObject { QType type; size_t refcnt; -} QObject; +}; /* Get the 'base' part of an object */ #define QOBJECT(obj) (&(obj)->base) @@ -66,7 +55,7 @@ typedef struct QObject { /* Initialize an object to default values */ static inline void qobject_init(QObject *obj, QType type) { - assert(QTYPE_NONE < type && type < QTYPE_MAX); + assert(QTYPE_NONE < type && type < QTYPE__MAX); obj->refcnt = 1; obj->type = type; } @@ -102,7 +91,7 @@ static inline void qobject_decref(QObject *obj) */ static inline QType qobject_type(const QObject *obj) { - assert(QTYPE_NONE < obj->type && obj->type < QTYPE_MAX); + assert(QTYPE_NONE < obj->type && obj->type < QTYPE__MAX); return obj->type; } diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h index 3eedcf4c8f..78fe6e86e3 100644 --- a/include/qemu/typedefs.h +++ b/include/qemu/typedefs.h @@ -80,6 +80,7 @@ typedef struct QEMUSGList QEMUSGList; typedef struct QEMUSizedBuffer QEMUSizedBuffer; typedef struct QEMUTimer QEMUTimer; typedef struct QEMUTimerListGroup QEMUTimerListGroup; +typedef struct QObject QObject; typedef struct RAMBlock RAMBlock; typedef struct Range Range; typedef struct SerialState SerialState; diff --git a/qobject/qobject.c b/qobject/qobject.c index 1df315ab01..a3ef14eb55 100644 --- a/qobject/qobject.c +++ b/qobject/qobject.c @@ -15,7 +15,7 @@ #include "qapi/qmp/qlist.h" #include "qapi/qmp/qstring.h" -static void (*qdestroy[QTYPE_MAX])(QObject *) = { +static void (*qdestroy[QTYPE__MAX])(QObject *) = { [QTYPE_NONE] = NULL, /* No such object exists */ [QTYPE_QNULL] = NULL, /* qnull_ is indestructible */ [QTYPE_QINT] = qint_destroy_obj, @@ -29,6 +29,6 @@ static void (*qdestroy[QTYPE_MAX])(QObject *) = { void qobject_destroy(QObject *obj) { assert(!obj->refcnt); - assert(QTYPE_QNULL < obj->type && obj->type < QTYPE_MAX); + assert(QTYPE_QNULL < obj->type && obj->type < QTYPE__MAX); qdestroy[obj->type](obj); } diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py index 2f2f7dfd80..2071846250 100644 --- a/scripts/qapi-types.py +++ b/scripts/qapi-types.py @@ -112,7 +112,7 @@ extern const int %(c_name)s_qtypes[]; def gen_alternate_qtypes(name, variants): ret = mcgen(''' -const int %(c_name)s_qtypes[QTYPE_MAX] = { +const int %(c_name)s_qtypes[QTYPE__MAX] = { ''', c_name=c_name(name)) @@ -233,8 +233,15 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor): self.defn += gen_type_cleanup(name) def visit_enum_type(self, name, info, values, prefix): - self._fwdecl += gen_enum(name, values, prefix) - self._fwdefn += gen_enum_lookup(name, values, prefix) + # Special case for our lone builtin enum type + # TODO use something cleaner than existence of info + if not info: + self._btin += gen_enum(name, values, prefix) + if do_builtins: + self.defn += gen_enum_lookup(name, values, prefix) + else: + self._fwdecl += gen_enum(name, values, prefix) + self._fwdefn += gen_enum_lookup(name, values, prefix) def visit_array_type(self, name, info, element_type): if isinstance(element_type, QAPISchemaBuiltinType): @@ -316,10 +323,11 @@ fdef.write(mcgen(''' ''', prefix=prefix)) +# To avoid circular headers, use only typedefs.h here, not qobject.h fdecl.write(mcgen(''' #include #include -#include "qapi/qmp/qobject.h" +#include "qemu/typedefs.h" ''')) schema = QAPISchema(input_file) diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py index 94cd11335e..7ceda18bdb 100644 --- a/scripts/qapi-visit.py +++ b/scripts/qapi-visit.py @@ -347,8 +347,15 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor): isinstance(entity, QAPISchemaObjectType)) def visit_enum_type(self, name, info, values, prefix): - self.decl += gen_visit_decl(name, scalar=True) - self.defn += gen_visit_enum(name) + # Special case for our lone builtin enum type + # TODO use something cleaner than existence of info + if not info: + self._btin += gen_visit_decl(name, scalar=True) + if do_builtins: + self.defn += gen_visit_enum(name) + else: + self.decl += gen_visit_decl(name, scalar=True) + self.defn += gen_visit_enum(name) def visit_array_type(self, name, info, element_type): decl = gen_visit_decl(name) diff --git a/scripts/qapi.py b/scripts/qapi.py index b336fbd57c..c9e4ad2d9e 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -34,6 +34,7 @@ builtin_types = { 'uint64': 'QTYPE_QINT', 'size': 'QTYPE_QINT', 'any': None, # any QType possible, actually + 'QType': 'QTYPE_QSTRING', } # Whitelist of commands allowed to return a non-dictionary @@ -1244,6 +1245,11 @@ class QAPISchema(object): self.the_empty_object_type = QAPISchemaObjectType(':empty', None, None, [], None) self._def_entity(self.the_empty_object_type) + self._def_entity(QAPISchemaEnumType('QType', None, + ['none', 'qnull', 'qint', + 'qstring', 'qdict', 'qlist', + 'qfloat', 'qbool'], + 'QTYPE')) def _make_implicit_enum_type(self, name, info, values): name = name + 'Kind' # Use namespace reserved by add_name() diff --git a/tests/qapi-schema/alternate-empty.out b/tests/qapi-schema/alternate-empty.out index 0f153b6f60..02b9876e76 100644 --- a/tests/qapi-schema/alternate-empty.out +++ b/tests/qapi-schema/alternate-empty.out @@ -2,3 +2,5 @@ object :empty alternate Alt case i: int enum AltKind ['i'] +enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool'] + prefix QTYPE diff --git a/tests/qapi-schema/comments.out b/tests/qapi-schema/comments.out index 9e2c656fa0..97be601897 100644 --- a/tests/qapi-schema/comments.out +++ b/tests/qapi-schema/comments.out @@ -1,2 +1,4 @@ object :empty +enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool'] + prefix QTYPE enum Status ['good', 'bad', 'ugly'] diff --git a/tests/qapi-schema/empty.out b/tests/qapi-schema/empty.out index 272b1616f4..6522940dc4 100644 --- a/tests/qapi-schema/empty.out +++ b/tests/qapi-schema/empty.out @@ -1 +1,3 @@ object :empty +enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool'] + prefix QTYPE diff --git a/tests/qapi-schema/event-case.out b/tests/qapi-schema/event-case.out index cdfd264f9c..6350d6497b 100644 --- a/tests/qapi-schema/event-case.out +++ b/tests/qapi-schema/event-case.out @@ -1,2 +1,4 @@ object :empty +enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool'] + prefix QTYPE event oops None diff --git a/tests/qapi-schema/flat-union-empty.out b/tests/qapi-schema/flat-union-empty.out index 0e0665af3b..eade2d5ac6 100644 --- a/tests/qapi-schema/flat-union-empty.out +++ b/tests/qapi-schema/flat-union-empty.out @@ -2,6 +2,8 @@ object :empty object Base member type: Empty optional=False enum Empty [] +enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool'] + prefix QTYPE object Union base Base tag type diff --git a/tests/qapi-schema/ident-with-escape.out b/tests/qapi-schema/ident-with-escape.out index f4542b12d8..453e0b2adb 100644 --- a/tests/qapi-schema/ident-with-escape.out +++ b/tests/qapi-schema/ident-with-escape.out @@ -1,5 +1,7 @@ object :empty object :obj-fooA-arg member bar1: str optional=False +enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool'] + prefix QTYPE command fooA :obj-fooA-arg -> None gen=True success_response=True diff --git a/tests/qapi-schema/include-relpath.out b/tests/qapi-schema/include-relpath.out index 9e2c656fa0..97be601897 100644 --- a/tests/qapi-schema/include-relpath.out +++ b/tests/qapi-schema/include-relpath.out @@ -1,2 +1,4 @@ object :empty +enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool'] + prefix QTYPE enum Status ['good', 'bad', 'ugly'] diff --git a/tests/qapi-schema/include-repetition.out b/tests/qapi-schema/include-repetition.out index 9e2c656fa0..97be601897 100644 --- a/tests/qapi-schema/include-repetition.out +++ b/tests/qapi-schema/include-repetition.out @@ -1,2 +1,4 @@ object :empty +enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool'] + prefix QTYPE enum Status ['good', 'bad', 'ugly'] diff --git a/tests/qapi-schema/include-simple.out b/tests/qapi-schema/include-simple.out index 9e2c656fa0..97be601897 100644 --- a/tests/qapi-schema/include-simple.out +++ b/tests/qapi-schema/include-simple.out @@ -1,2 +1,4 @@ object :empty +enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool'] + prefix QTYPE enum Status ['good', 'bad', 'ugly'] diff --git a/tests/qapi-schema/indented-expr.out b/tests/qapi-schema/indented-expr.out index 226d300798..ce37ff572b 100644 --- a/tests/qapi-schema/indented-expr.out +++ b/tests/qapi-schema/indented-expr.out @@ -1,4 +1,6 @@ object :empty +enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool'] + prefix QTYPE command eins None -> None gen=True success_response=True command zwei None -> None diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out index 0724a9f932..b87cfba599 100644 --- a/tests/qapi-schema/qapi-schema-test.out +++ b/tests/qapi-schema/qapi-schema-test.out @@ -101,6 +101,8 @@ object NestedEnumsOne member enum4: EnumOne optional=True enum QEnumTwo ['value1', 'value2'] prefix QENUM_TWO +enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool'] + prefix QTYPE object TestStruct member integer: int optional=False member boolean: bool optional=False diff --git a/tests/qapi-schema/union-clash-data.out b/tests/qapi-schema/union-clash-data.out index cea8551c4c..f5752f4595 100644 --- a/tests/qapi-schema/union-clash-data.out +++ b/tests/qapi-schema/union-clash-data.out @@ -1,6 +1,8 @@ object :empty object :obj-int-wrapper member data: int optional=False +enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool'] + prefix QTYPE object TestUnion member type: TestUnionKind optional=False case data: :obj-int-wrapper diff --git a/tests/qapi-schema/union-empty.out b/tests/qapi-schema/union-empty.out index 9c89fd10ba..bdf17e5b29 100644 --- a/tests/qapi-schema/union-empty.out +++ b/tests/qapi-schema/union-empty.out @@ -1,4 +1,6 @@ object :empty +enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool'] + prefix QTYPE object Union member type: UnionKind optional=False enum UnionKind [] -- cgit v1.2.3-55-g7522 From 0426d53c6530606bf7641b83f2b755fe61c280ee Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Tue, 1 Dec 2015 22:20:48 -0700 Subject: qapi: Simplify visiting of alternate types Previously, working with alternates required two lookup arrays and some indirection: for type Foo, we created Foo_qtypes[] which maps each qtype to a value of the generated FooKind enum, then look up that value in FooKind_lookup[] like we do for other union types. This has a couple of subtle bugs. First, the generator was creating a call with a parameter '(int *) &(*obj)->type' where type is an enum type; this is unsafe if the compiler chooses to store the enum type in a different size than int, where assigning through the wrong size pointer can corrupt data or cause a SIGBUS. Related bug, not not fixed in this patch: qapi-visit.py's gen_visit_enum() generates a cast of its enum * argument to int *. Marked FIXME. Second, since the values of the FooKind enum start at zero, all entries of the Foo_qtypes[] array that were not explicitly initialized will map to the same branch of the union as the first member of the alternate, rather than triggering a desired failure in visit_get_next_type(). Fortunately, the bug seldom bites; the very next thing the input visitor does is try to parse the incoming JSON with the wrong parser, which normally fails; the output visitor is not used with a C struct in that state, and the dealloc visitor has nothing to clean up (so there is no leak). However, the second bug IS observable in one case: parsing an integer causes unusual behavior in an alternate that contains at least a 'number' member but no 'int' member, because the 'number' parser accepts QTYPE_QINT in addition to the expected QTYPE_QFLOAT (that is, since 'int' is not a member, the type QTYPE_QINT accidentally maps to FooKind 0; if this enum value is the 'number' branch the integer parses successfully, but if the 'number' branch is not first, some other branch tries to parse the integer and rejects it). A later patch will worry about fixing alternates to always parse all inputs that a non-alternate 'number' would accept, for now this is still marked FIXME in the updated test-qmp-input-visitor.c, to merely point out that new undesired behavior of 'ans' matches the existing undesired behavior of 'asn'. This patch fixes the default-initialization bug by deleting the indirection, and modifying get_next_type() to directly assign a QTypeCode parameter. This in turn fixes the type-casting bug, as we are no longer casting a pointer to enum to a questionable size. There is no longer a need to generate an implicit FooKind enum associated with the alternate type (since the QMP wire format never uses the stringized counterparts of the C union member names). Since the updated visit_get_next_type() does not know which qtypes are expected, the generated visitor is modified to generate an error statement if an unexpected type is encountered. Callers now have to know the QTYPE_* mapping when looking at the discriminator; but so far, only the testsuite was even using the C struct of an alternate types. I considered the possibility of keeping the internal enum FooKind, but initialized differently than most generated arrays, as in: typedef enum FooKind { FOO_KIND_A = QTYPE_QDICT, FOO_KIND_B = QTYPE_QINT, } FooKind; to create nicer aliases for knowing when to use foo->a or foo->b when inspecting foo->type; but it turned out to add too much complexity, especially without a client. There is a user-visible side effect to this change, but I consider it to be an improvement. Previously, the invalid QMP command: {"execute":"blockdev-add", "arguments":{"options": {"driver":"raw", "id":"a", "file":true}}} failed with: {"error": {"class": "GenericError", "desc": "Invalid parameter type for 'file', expected: QDict"}} (visit_get_next_type() succeeded, and the error comes from the visit_type_BlockdevOptions() expecting {}; there is no mention of the fact that a string would also work). Now it fails with: {"error": {"class": "GenericError", "desc": "Invalid parameter type for 'file', expected: BlockdevRef"}} (the error when the next type doesn't match any expected types for the overall alternate). Signed-off-by: Eric Blake Message-Id: <1449033659-25497-5-git-send-email-eblake@redhat.com> Signed-off-by: Markus Armbruster --- docs/qapi-code-gen.txt | 3 --- include/qapi/visitor-impl.h | 3 ++- include/qapi/visitor.h | 8 +++++++- qapi/qapi-visit-core.c | 4 ++-- qapi/qmp-input-visitor.c | 4 ++-- scripts/qapi-types.py | 34 ---------------------------------- scripts/qapi-visit.py | 15 ++++++++++----- scripts/qapi.py | 18 +++++++++++++----- tests/qapi-schema/alternate-empty.out | 1 - tests/qapi-schema/qapi-schema-test.out | 8 -------- tests/test-qmp-input-visitor.c | 31 ++++++++++++++++--------------- tests/test-qmp-output-visitor.c | 4 ++-- 12 files changed, 54 insertions(+), 79 deletions(-) (limited to 'include') diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt index 79bf072695..128f074a2d 100644 --- a/docs/qapi-code-gen.txt +++ b/docs/qapi-code-gen.txt @@ -384,9 +384,6 @@ where each branch of the union names a QAPI type. For example: 'data': { 'definition': 'BlockdevOptions', 'reference': 'str' } } -Just like for a simple union, an implicit C enum 'NameKind' is created -to enumerate the branches for the alternate 'Name'. - Unlike a union, the discriminator string is never passed on the wire for the Client JSON Protocol. Instead, the value's JSON type serves as an implicit discriminator, which in turn means that an alternate diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h index 8c0ba57292..7cd1313129 100644 --- a/include/qapi/visitor-impl.h +++ b/include/qapi/visitor-impl.h @@ -32,7 +32,8 @@ struct Visitor void (*type_enum)(Visitor *v, int *obj, const char * const strings[], const char *kind, const char *name, Error **errp); - void (*get_next_type)(Visitor *v, int *kind, const int *qobjects, + /* May be NULL; only needed for input visitors. */ + void (*get_next_type)(Visitor *v, QType *type, const char *name, Error **errp); void (*type_int)(Visitor *v, int64_t *obj, const char *name, Error **errp); diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h index a2ad66cf8f..6d25ad27a2 100644 --- a/include/qapi/visitor.h +++ b/include/qapi/visitor.h @@ -38,7 +38,13 @@ GenericList *visit_next_list(Visitor *v, GenericList **list, Error **errp); void visit_end_list(Visitor *v, Error **errp); void visit_optional(Visitor *v, bool *present, const char *name, Error **errp); -void visit_get_next_type(Visitor *v, int *obj, const int *qtypes, + +/** + * Determine the qtype of the item @name in the current object visit. + * For input visitors, set *@type to the correct qtype of a qapi + * alternate type; for other visitors, leave *@type unchanged. + */ +void visit_get_next_type(Visitor *v, QType *type, const char *name, Error **errp); void visit_type_enum(Visitor *v, int *obj, const char * const strings[], const char *kind, const char *name, Error **errp); diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c index 59ed5067fa..850ca034cb 100644 --- a/qapi/qapi-visit-core.c +++ b/qapi/qapi-visit-core.c @@ -81,11 +81,11 @@ void visit_optional(Visitor *v, bool *present, const char *name, } } -void visit_get_next_type(Visitor *v, int *obj, const int *qtypes, +void visit_get_next_type(Visitor *v, QType *type, const char *name, Error **errp) { if (v->get_next_type) { - v->get_next_type(v, obj, qtypes, name, errp); + v->get_next_type(v, type, name, errp); } } diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c index eb6e110300..d398de743d 100644 --- a/qapi/qmp-input-visitor.c +++ b/qapi/qmp-input-visitor.c @@ -208,7 +208,7 @@ static void qmp_input_end_list(Visitor *v, Error **errp) qmp_input_pop(qiv, errp); } -static void qmp_input_get_next_type(Visitor *v, int *kind, const int *qobjects, +static void qmp_input_get_next_type(Visitor *v, QType *type, const char *name, Error **errp) { QmpInputVisitor *qiv = to_qiv(v); @@ -218,7 +218,7 @@ static void qmp_input_get_next_type(Visitor *v, int *kind, const int *qobjects, error_setg(errp, QERR_MISSING_PARAMETER, name ? name : "null"); return; } - *kind = qobjects[qobject_type(qobj)]; + *type = qobject_type(qobj); } static void qmp_input_type_int(Visitor *v, int64_t *obj, const char *name, diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py index 2071846250..84ec858419 100644 --- a/scripts/qapi-types.py +++ b/scripts/qapi-types.py @@ -101,38 +101,6 @@ static inline %(base)s *qapi_%(c_name)s_base(const %(c_name)s *obj) c_name=c_name(name), base=base.c_name()) -def gen_alternate_qtypes_decl(name): - return mcgen(''' - -extern const int %(c_name)s_qtypes[]; -''', - c_name=c_name(name)) - - -def gen_alternate_qtypes(name, variants): - ret = mcgen(''' - -const int %(c_name)s_qtypes[QTYPE__MAX] = { -''', - c_name=c_name(name)) - - for var in variants.variants: - qtype = var.type.alternate_qtype() - assert qtype - - ret += mcgen(''' - [%(qtype)s] = %(enum_const)s, -''', - qtype=qtype, - enum_const=c_enum_const(variants.tag_member.type.name, - var.name)) - - ret += mcgen(''' -}; -''') - return ret - - def gen_variants(variants): # FIXME: What purpose does data serve, besides preventing a union that # has a branch named 'data'? We use it in qapi-visit.py to decide @@ -264,9 +232,7 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor): def visit_alternate_type(self, name, info, variants): self._fwdecl += gen_fwd_object_or_array(name) - self._fwdefn += gen_alternate_qtypes(name, variants) self.decl += gen_object(name, None, [variants.tag_member], variants) - self.decl += gen_alternate_qtypes_decl(name) self._gen_type_cleanup(name) # If you link code generated from multiple schemata, you want only one diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py index 7ceda18bdb..4797d6e050 100644 --- a/scripts/qapi-visit.py +++ b/scripts/qapi-visit.py @@ -172,6 +172,7 @@ out: def gen_visit_enum(name): + # FIXME cast from enum *obj to int * invalidly assumes enum is int return mcgen(''' void visit_type_%(c_name)s(Visitor *v, %(c_name)s *obj, const char *name, Error **errp) @@ -193,7 +194,7 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, Error if (err) { goto out; } - visit_get_next_type(v, (int*) &(*obj)->type, %(c_name)s_qtypes, name, &err); + visit_get_next_type(v, &(*obj)->type, name, &err); if (err) { goto out_obj; } @@ -201,20 +202,22 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, Error ''', c_name=c_name(name)) + # FIXME: When 'number' but not 'int' is present in the alternate, we + # should allow QTYPE_INT to promote to QTYPE_FLOAT. for var in variants.variants: ret += mcgen(''' case %(case)s: visit_type_%(c_type)s(v, &(*obj)->u.%(c_name)s, name, &err); break; ''', - case=c_enum_const(variants.tag_member.type.name, - var.name), + case=var.type.alternate_qtype(), c_type=var.type.c_name(), c_name=c_name(var.name)) ret += mcgen(''' default: - abort(); + error_setg(&err, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", + "%(name)s"); } out_obj: error_propagate(errp, err); @@ -223,7 +226,8 @@ out_obj: out: error_propagate(errp, err); } -''') +''', + name=name) return ret @@ -437,6 +441,7 @@ fdef.write(mcgen(''' fdecl.write(mcgen(''' #include "qapi/visitor.h" +#include "qapi/qmp/qerror.h" #include "%(prefix)sqapi-types.h" ''', diff --git a/scripts/qapi.py b/scripts/qapi.py index c9e4ad2d9e..2b46dd095f 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -635,8 +635,8 @@ def check_alternate(expr, expr_info): for (key, value) in members.items(): check_name(expr_info, "Member of alternate '%s'" % name, key) - # Check for conflicts in the generated enum - c_key = camel_to_upper(key) + # Check for conflicts in the branch names + c_key = c_name(key) if c_key in values: raise QAPIExprError(expr_info, "Alternate '%s' member '%s' clashes with '%s'" @@ -1092,8 +1092,11 @@ class QAPISchemaObjectTypeVariants(object): assert isinstance(self.tag_member.type, QAPISchemaEnumType) for v in self.variants: v.check(schema) - assert v.name in self.tag_member.type.values - if isinstance(v.type, QAPISchemaObjectType): + # Union names must match enum values; alternate names are + # checked separately. Use 'seen' to tell the two apart. + if seen: + assert v.name in self.tag_member.type.values + assert isinstance(v.type, QAPISchemaObjectType) v.type.check(schema) def check_clash(self, schema, info, seen): @@ -1135,6 +1138,11 @@ class QAPISchemaAlternateType(QAPISchemaType): # Not calling self.variants.check_clash(), because there's nothing # to clash with self.variants.check(schema, {}) + # Alternate branch names have no relation to the tag enum values; + # so we have to check for potential name collisions ourselves. + seen = {} + for v in self.variants.variants: + v.check_clash(self.info, seen) def json_type(self): return 'value' @@ -1342,7 +1350,7 @@ class QAPISchema(object): data = expr['data'] variants = [self._make_variant(key, value) for (key, value) in data.iteritems()] - tag_member = self._make_implicit_tag(name, info, variants) + tag_member = QAPISchemaObjectTypeMember('type', 'QType', False) self._def_entity( QAPISchemaAlternateType(name, info, QAPISchemaObjectTypeVariants(None, diff --git a/tests/qapi-schema/alternate-empty.out b/tests/qapi-schema/alternate-empty.out index 02b9876e76..f78f174111 100644 --- a/tests/qapi-schema/alternate-empty.out +++ b/tests/qapi-schema/alternate-empty.out @@ -1,6 +1,5 @@ object :empty alternate Alt case i: int -enum AltKind ['i'] enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool'] prefix QTYPE diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out index b87cfba599..2c546b708a 100644 --- a/tests/qapi-schema/qapi-schema-test.out +++ b/tests/qapi-schema/qapi-schema-test.out @@ -56,27 +56,21 @@ object :obj-user_def_cmd2-arg alternate AltIntNum case i: int case n: number -enum AltIntNumKind ['i', 'n'] alternate AltNumInt case n: number case i: int -enum AltNumIntKind ['n', 'i'] alternate AltNumStr case n: number case s: str -enum AltNumStrKind ['n', 's'] alternate AltStrBool case s: str case b: bool -enum AltStrBoolKind ['s', 'b'] alternate AltStrInt case s: str case i: int -enum AltStrIntKind ['s', 'i'] alternate AltStrNum case s: str case n: number -enum AltStrNumKind ['s', 'n'] event EVENT_A None event EVENT_B None event EVENT_C :obj-EVENT_C-arg @@ -114,7 +108,6 @@ alternate UserDefAlternate case uda: UserDefA case s: str case i: int -enum UserDefAlternateKind ['uda', 's', 'i'] object UserDefB member intb: int optional=False member a-b: bool optional=True @@ -180,7 +173,6 @@ event __ORG.QEMU_X-EVENT __org.qemu_x-Struct alternate __org.qemu_x-Alt case __org.qemu_x-branch: str case b: __org.qemu_x-Base -enum __org.qemu_x-AltKind ['__org.qemu_x-branch', 'b'] object __org.qemu_x-Base member __org.qemu_x-member1: __org.qemu_x-Enum optional=False enum __org.qemu_x-Enum ['__org.qemu_x-value'] diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c index d48ebdd62f..43b9e18912 100644 --- a/tests/test-qmp-input-visitor.c +++ b/tests/test-qmp-input-visitor.c @@ -312,13 +312,13 @@ static void test_visitor_in_alternate(TestInputVisitorData *data, v = visitor_input_test_init(data, "42"); visit_type_UserDefAlternate(v, &tmp, NULL, &error_abort); - g_assert_cmpint(tmp->type, ==, USER_DEF_ALTERNATE_KIND_I); + g_assert_cmpint(tmp->type, ==, QTYPE_QINT); g_assert_cmpint(tmp->u.i, ==, 42); qapi_free_UserDefAlternate(tmp); v = visitor_input_test_init(data, "'string'"); visit_type_UserDefAlternate(v, &tmp, NULL, &error_abort); - g_assert_cmpint(tmp->type, ==, USER_DEF_ALTERNATE_KIND_S); + g_assert_cmpint(tmp->type, ==, QTYPE_QSTRING); g_assert_cmpstr(tmp->u.s, ==, "string"); qapi_free_UserDefAlternate(tmp); @@ -347,36 +347,37 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data, error_free_or_abort(&err); qapi_free_AltStrBool(asb); - /* FIXME: Order of alternate should not affect semantics; asn should - * parse the same as ans */ + /* FIXME: integer should parse as number */ v = visitor_input_test_init(data, "42"); visit_type_AltStrNum(v, &asn, NULL, &err); - /* FIXME g_assert_cmpint(asn->type, == ALT_STR_NUM_KIND_N); */ + /* FIXME g_assert_cmpint(asn->type, ==, QTYPE_QFLOAT); */ /* FIXME g_assert_cmpfloat(asn->u.n, ==, 42); */ error_free_or_abort(&err); qapi_free_AltStrNum(asn); + /* FIXME: integer should parse as number */ v = visitor_input_test_init(data, "42"); - visit_type_AltNumStr(v, &ans, NULL, &error_abort); - g_assert_cmpint(ans->type, ==, ALT_NUM_STR_KIND_N); - g_assert_cmpfloat(ans->u.n, ==, 42); + visit_type_AltNumStr(v, &ans, NULL, &err); + /* FIXME g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT); */ + /* FIXME g_assert_cmpfloat(ans->u.n, ==, 42); */ + error_free_or_abort(&err); qapi_free_AltNumStr(ans); v = visitor_input_test_init(data, "42"); visit_type_AltStrInt(v, &asi, NULL, &error_abort); - g_assert_cmpint(asi->type, ==, ALT_STR_INT_KIND_I); + g_assert_cmpint(asi->type, ==, QTYPE_QINT); g_assert_cmpint(asi->u.i, ==, 42); qapi_free_AltStrInt(asi); v = visitor_input_test_init(data, "42"); visit_type_AltIntNum(v, &ain, NULL, &error_abort); - g_assert_cmpint(ain->type, ==, ALT_INT_NUM_KIND_I); + g_assert_cmpint(ain->type, ==, QTYPE_QINT); g_assert_cmpint(ain->u.i, ==, 42); qapi_free_AltIntNum(ain); v = visitor_input_test_init(data, "42"); visit_type_AltNumInt(v, &ani, NULL, &error_abort); - g_assert_cmpint(ani->type, ==, ALT_NUM_INT_KIND_I); + g_assert_cmpint(ani->type, ==, QTYPE_QINT); g_assert_cmpint(ani->u.i, ==, 42); qapi_free_AltNumInt(ani); @@ -389,13 +390,13 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data, v = visitor_input_test_init(data, "42.5"); visit_type_AltStrNum(v, &asn, NULL, &error_abort); - g_assert_cmpint(asn->type, ==, ALT_STR_NUM_KIND_N); + g_assert_cmpint(asn->type, ==, QTYPE_QFLOAT); g_assert_cmpfloat(asn->u.n, ==, 42.5); qapi_free_AltStrNum(asn); v = visitor_input_test_init(data, "42.5"); visit_type_AltNumStr(v, &ans, NULL, &error_abort); - g_assert_cmpint(ans->type, ==, ALT_NUM_STR_KIND_N); + g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT); g_assert_cmpfloat(ans->u.n, ==, 42.5); qapi_free_AltNumStr(ans); @@ -406,13 +407,13 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data, v = visitor_input_test_init(data, "42.5"); visit_type_AltIntNum(v, &ain, NULL, &error_abort); - g_assert_cmpint(ain->type, ==, ALT_INT_NUM_KIND_N); + g_assert_cmpint(ain->type, ==, QTYPE_QFLOAT); g_assert_cmpfloat(ain->u.n, ==, 42.5); qapi_free_AltIntNum(ain); v = visitor_input_test_init(data, "42.5"); visit_type_AltNumInt(v, &ani, NULL, &error_abort); - g_assert_cmpint(ani->type, ==, ALT_NUM_INT_KIND_N); + g_assert_cmpint(ani->type, ==, QTYPE_QFLOAT); g_assert_cmpfloat(ani->u.n, ==, 42.5); qapi_free_AltNumInt(ani); } diff --git a/tests/test-qmp-output-visitor.c b/tests/test-qmp-output-visitor.c index 4196e66dde..30784424e4 100644 --- a/tests/test-qmp-output-visitor.c +++ b/tests/test-qmp-output-visitor.c @@ -428,7 +428,7 @@ static void test_visitor_out_alternate(TestOutputVisitorData *data, UserDefAlternate *tmp; tmp = g_new0(UserDefAlternate, 1); - tmp->type = USER_DEF_ALTERNATE_KIND_I; + tmp->type = QTYPE_QINT; tmp->u.i = 42; visit_type_UserDefAlternate(data->ov, &tmp, NULL, &error_abort); @@ -441,7 +441,7 @@ static void test_visitor_out_alternate(TestOutputVisitorData *data, qobject_decref(arg); tmp = g_new0(UserDefAlternate, 1); - tmp->type = USER_DEF_ALTERNATE_KIND_S; + tmp->type = QTYPE_QSTRING; tmp->u.s = g_strdup("hello"); visit_type_UserDefAlternate(data->ov, &tmp, NULL, &error_abort); -- cgit v1.2.3-55-g7522 From d00341af384665d259af475b14c96bb8414df415 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Tue, 1 Dec 2015 22:20:51 -0700 Subject: qapi: Fix alternates that accept 'number' but not 'int' The QMP input visitor allows integral values to be assigned by promotion to a QTYPE_QFLOAT. However, when parsing an alternate, we did not take this into account, such that an alternate that accepts 'number' and some other type, but not 'int', would reject integral values. With this patch, we now have the following desirable table: alternate has case selected for 'int' 'number' QTYPE_QINT QTYPE_QFLOAT no no error error no yes 'number' 'number' yes no 'int' error yes yes 'int' 'number' While it is unlikely that we will ever use 'number' in an alternate other than in the testsuite, it never hurts to be more precise in what we allow. Signed-off-by: Eric Blake Message-Id: <1449033659-25497-8-git-send-email-eblake@redhat.com> Signed-off-by: Markus Armbruster --- include/qapi/visitor-impl.h | 2 +- include/qapi/visitor.h | 3 ++- qapi/qapi-visit-core.c | 4 ++-- qapi/qmp-input-visitor.c | 5 ++++- scripts/qapi-visit.py | 11 +++++++---- tests/test-qmp-input-visitor.c | 16 ++++++---------- 6 files changed, 22 insertions(+), 19 deletions(-) (limited to 'include') diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h index 7cd1313129..74196847fa 100644 --- a/include/qapi/visitor-impl.h +++ b/include/qapi/visitor-impl.h @@ -33,7 +33,7 @@ struct Visitor void (*type_enum)(Visitor *v, int *obj, const char * const strings[], const char *kind, const char *name, Error **errp); /* May be NULL; only needed for input visitors. */ - void (*get_next_type)(Visitor *v, QType *type, + void (*get_next_type)(Visitor *v, QType *type, bool promote_int, const char *name, Error **errp); void (*type_int)(Visitor *v, int64_t *obj, const char *name, Error **errp); diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h index 6d25ad27a2..1414de1b0d 100644 --- a/include/qapi/visitor.h +++ b/include/qapi/visitor.h @@ -43,8 +43,9 @@ void visit_optional(Visitor *v, bool *present, const char *name, * Determine the qtype of the item @name in the current object visit. * For input visitors, set *@type to the correct qtype of a qapi * alternate type; for other visitors, leave *@type unchanged. + * If @promote_int, treat integers as QTYPE_FLOAT. */ -void visit_get_next_type(Visitor *v, QType *type, +void visit_get_next_type(Visitor *v, QType *type, bool promote_int, const char *name, Error **errp); void visit_type_enum(Visitor *v, int *obj, const char * const strings[], const char *kind, const char *name, Error **errp); diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c index 850ca034cb..cee76bc649 100644 --- a/qapi/qapi-visit-core.c +++ b/qapi/qapi-visit-core.c @@ -81,11 +81,11 @@ void visit_optional(Visitor *v, bool *present, const char *name, } } -void visit_get_next_type(Visitor *v, QType *type, +void visit_get_next_type(Visitor *v, QType *type, bool promote_int, const char *name, Error **errp) { if (v->get_next_type) { - v->get_next_type(v, type, name, errp); + v->get_next_type(v, type, promote_int, name, errp); } } diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c index d398de743d..26b7414178 100644 --- a/qapi/qmp-input-visitor.c +++ b/qapi/qmp-input-visitor.c @@ -208,7 +208,7 @@ static void qmp_input_end_list(Visitor *v, Error **errp) qmp_input_pop(qiv, errp); } -static void qmp_input_get_next_type(Visitor *v, QType *type, +static void qmp_input_get_next_type(Visitor *v, QType *type, bool promote_int, const char *name, Error **errp) { QmpInputVisitor *qiv = to_qiv(v); @@ -219,6 +219,9 @@ static void qmp_input_get_next_type(Visitor *v, QType *type, return; } *type = qobject_type(qobj); + if (promote_int && *type == QTYPE_QINT) { + *type = QTYPE_QFLOAT; + } } static void qmp_input_type_int(Visitor *v, int64_t *obj, const char *name, diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py index 4797d6e050..b93690b608 100644 --- a/scripts/qapi-visit.py +++ b/scripts/qapi-visit.py @@ -184,6 +184,11 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s *obj, const char *name, Error def gen_visit_alternate(name, variants): + promote_int = 'true' + for var in variants.variants: + if var.type.alternate_qtype() == 'QTYPE_QINT': + promote_int = 'false' + ret = mcgen(''' void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, Error **errp) @@ -194,16 +199,14 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, Error if (err) { goto out; } - visit_get_next_type(v, &(*obj)->type, name, &err); + visit_get_next_type(v, &(*obj)->type, %(promote_int)s, name, &err); if (err) { goto out_obj; } switch ((*obj)->type) { ''', - c_name=c_name(name)) + c_name=c_name(name), promote_int=promote_int) - # FIXME: When 'number' but not 'int' is present in the alternate, we - # should allow QTYPE_INT to promote to QTYPE_FLOAT. for var in variants.variants: ret += mcgen(''' case %(case)s: diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c index 43b9e18912..b4a5bee6a5 100644 --- a/tests/test-qmp-input-visitor.c +++ b/tests/test-qmp-input-visitor.c @@ -347,20 +347,16 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data, error_free_or_abort(&err); qapi_free_AltStrBool(asb); - /* FIXME: integer should parse as number */ v = visitor_input_test_init(data, "42"); - visit_type_AltStrNum(v, &asn, NULL, &err); - /* FIXME g_assert_cmpint(asn->type, ==, QTYPE_QFLOAT); */ - /* FIXME g_assert_cmpfloat(asn->u.n, ==, 42); */ - error_free_or_abort(&err); + visit_type_AltStrNum(v, &asn, NULL, &error_abort); + g_assert_cmpint(asn->type, ==, QTYPE_QFLOAT); + g_assert_cmpfloat(asn->u.n, ==, 42); qapi_free_AltStrNum(asn); - /* FIXME: integer should parse as number */ v = visitor_input_test_init(data, "42"); - visit_type_AltNumStr(v, &ans, NULL, &err); - /* FIXME g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT); */ - /* FIXME g_assert_cmpfloat(ans->u.n, ==, 42); */ - error_free_or_abort(&err); + visit_type_AltNumStr(v, &ans, NULL, &error_abort); + g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT); + g_assert_cmpfloat(ans->u.n, ==, 42); qapi_free_AltNumStr(ans); v = visitor_input_test_init(data, "42"); -- cgit v1.2.3-55-g7522 From 5cdc8831a795fb8452d7e34f644202fd724e122a Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Tue, 1 Dec 2015 22:20:52 -0700 Subject: qapi: Simplify visits of optional fields None of the visitor callbacks would set an error when testing if an optional field was present; make this part of the interface contract by eliminating the errp argument. The resulting generated code has a nice diff: |- visit_optional(v, &has_fdset_id, "fdset-id", &err); |- if (err) { |- goto out; |- } |+ visit_optional(v, &has_fdset_id, "fdset-id"); | if (has_fdset_id) { | visit_type_int(v, &fdset_id, "fdset-id", &err); | if (err) { | goto out; | } | } Signed-off-by: Eric Blake Message-Id: <1449033659-25497-9-git-send-email-eblake@redhat.com> Signed-off-by: Markus Armbruster --- include/qapi/visitor-impl.h | 5 ++--- include/qapi/visitor.h | 10 ++++++++-- qapi/opts-visitor.c | 2 +- qapi/qapi-visit-core.c | 5 ++--- qapi/qmp-input-visitor.c | 3 +-- qapi/string-input-visitor.c | 3 +-- scripts/qapi.py | 8 ++------ 7 files changed, 17 insertions(+), 19 deletions(-) (limited to 'include') diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h index 74196847fa..44a21b79d6 100644 --- a/include/qapi/visitor-impl.h +++ b/include/qapi/visitor-impl.h @@ -44,9 +44,8 @@ struct Visitor void (*type_any)(Visitor *v, QObject **obj, const char *name, Error **errp); - /* May be NULL */ - void (*optional)(Visitor *v, bool *present, const char *name, - Error **errp); + /* May be NULL; most useful for input visitors. */ + void (*optional)(Visitor *v, bool *present, const char *name); void (*type_uint8)(Visitor *v, uint8_t *obj, const char *name, Error **errp); void (*type_uint16)(Visitor *v, uint16_t *obj, const char *name, Error **errp); diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h index 1414de1b0d..9be60d428d 100644 --- a/include/qapi/visitor.h +++ b/include/qapi/visitor.h @@ -36,8 +36,14 @@ void visit_end_implicit_struct(Visitor *v, Error **errp); void visit_start_list(Visitor *v, const char *name, Error **errp); GenericList *visit_next_list(Visitor *v, GenericList **list, Error **errp); void visit_end_list(Visitor *v, Error **errp); -void visit_optional(Visitor *v, bool *present, const char *name, - Error **errp); + +/** + * Check if an optional member @name of an object needs visiting. + * For input visitors, set *@present according to whether the + * corresponding visit_type_*() needs calling; for other visitors, + * leave *@present unchanged. + */ +void visit_optional(Visitor *v, bool *present, const char *name); /** * Determine the qtype of the item @name in the current object visit. diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c index cd10392f18..ef5fb8b815 100644 --- a/qapi/opts-visitor.c +++ b/qapi/opts-visitor.c @@ -488,7 +488,7 @@ opts_type_size(Visitor *v, uint64_t *obj, const char *name, Error **errp) static void -opts_optional(Visitor *v, bool *present, const char *name, Error **errp) +opts_optional(Visitor *v, bool *present, const char *name) { OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v); diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c index cee76bc649..e07d6f962f 100644 --- a/qapi/qapi-visit-core.c +++ b/qapi/qapi-visit-core.c @@ -73,11 +73,10 @@ void visit_end_union(Visitor *v, bool data_present, Error **errp) } } -void visit_optional(Visitor *v, bool *present, const char *name, - Error **errp) +void visit_optional(Visitor *v, bool *present, const char *name) { if (v->optional) { - v->optional(v, present, name, errp); + v->optional(v, present, name); } } diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c index 26b7414178..932b5f3ced 100644 --- a/qapi/qmp-input-visitor.c +++ b/qapi/qmp-input-visitor.c @@ -303,8 +303,7 @@ static void qmp_input_type_any(Visitor *v, QObject **obj, const char *name, *obj = qobj; } -static void qmp_input_optional(Visitor *v, bool *present, const char *name, - Error **errp) +static void qmp_input_optional(Visitor *v, bool *present, const char *name) { QmpInputVisitor *qiv = to_qiv(v); QObject *qobj = qmp_input_get_object(qiv, name, true); diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c index bbd6a5456c..dee780a2da 100644 --- a/qapi/string-input-visitor.c +++ b/qapi/string-input-visitor.c @@ -299,8 +299,7 @@ static void parse_type_number(Visitor *v, double *obj, const char *name, *obj = val; } -static void parse_optional(Visitor *v, bool *present, const char *name, - Error **errp) +static void parse_optional(Visitor *v, bool *present, const char *name) { StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v); diff --git a/scripts/qapi.py b/scripts/qapi.py index 7e6c396a1d..8bf41db4e2 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -1656,15 +1656,11 @@ def gen_visit_fields(members, prefix='', need_cast=False, skiperr=False): for memb in members: if memb.optional: ret += mcgen(''' - visit_optional(v, &%(prefix)shas_%(c_name)s, "%(name)s", %(errp)s); + visit_optional(v, &%(prefix)shas_%(c_name)s, "%(name)s"); + if (%(prefix)shas_%(c_name)s) { ''', prefix=prefix, c_name=c_name(memb.name), name=memb.name, errp=errparg) - ret += gen_err_check(skiperr=skiperr) - ret += mcgen(''' - if (%(prefix)shas_%(c_name)s) { -''', - prefix=prefix, c_name=c_name(memb.name)) push_indent() # Ugly: sometimes we need to cast away const -- cgit v1.2.3-55-g7522 From 29637a6ee913df8fcdf371426ee48956b945b618 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Tue, 1 Dec 2015 22:20:53 -0700 Subject: qapi: Shorter visits of optional fields For less code, reflect the determined boolean value of an optional visit back to the caller instead of making the caller read the boolean after the fact. The resulting generated code has the following diff: |- visit_optional(v, &has_fdset_id, "fdset-id"); |- if (has_fdset_id) { |+ if (visit_optional(v, &has_fdset_id, "fdset-id")) { | visit_type_int(v, &fdset_id, "fdset-id", &err); | if (err) { | goto out; | } | } Signed-off-by: Eric Blake Message-Id: <1449033659-25497-10-git-send-email-eblake@redhat.com> Signed-off-by: Markus Armbruster --- include/qapi/visitor.h | 4 ++-- qapi/qapi-visit-core.c | 3 ++- scripts/qapi.py | 3 +-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h index 9be60d428d..a14a16d755 100644 --- a/include/qapi/visitor.h +++ b/include/qapi/visitor.h @@ -41,9 +41,9 @@ void visit_end_list(Visitor *v, Error **errp); * Check if an optional member @name of an object needs visiting. * For input visitors, set *@present according to whether the * corresponding visit_type_*() needs calling; for other visitors, - * leave *@present unchanged. + * leave *@present unchanged. Return *@present for convenience. */ -void visit_optional(Visitor *v, bool *present, const char *name); +bool visit_optional(Visitor *v, bool *present, const char *name); /** * Determine the qtype of the item @name in the current object visit. diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c index e07d6f962f..6d63e40234 100644 --- a/qapi/qapi-visit-core.c +++ b/qapi/qapi-visit-core.c @@ -73,11 +73,12 @@ void visit_end_union(Visitor *v, bool data_present, Error **errp) } } -void visit_optional(Visitor *v, bool *present, const char *name) +bool visit_optional(Visitor *v, bool *present, const char *name) { if (v->optional) { v->optional(v, present, name); } + return *present; } void visit_get_next_type(Visitor *v, QType *type, bool promote_int, diff --git a/scripts/qapi.py b/scripts/qapi.py index 8bf41db4e2..58ecdf2a95 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -1656,8 +1656,7 @@ def gen_visit_fields(members, prefix='', need_cast=False, skiperr=False): for memb in members: if memb.optional: ret += mcgen(''' - visit_optional(v, &%(prefix)shas_%(c_name)s, "%(name)s"); - if (%(prefix)shas_%(c_name)s) { + if (visit_optional(v, &%(prefix)shas_%(c_name)s, "%(name)s")) { ''', prefix=prefix, c_name=c_name(memb.name), name=memb.name, errp=errparg) -- cgit v1.2.3-55-g7522