QAPI patches for 2015-12-17
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJWcmVVAAoJEDhwtADrkYZTgLwP/2xkMCMhqvepE/wVM7MNygn8 F1KuOd+9Qtt9mhr1MZlBmP1FRMhgIxQ3Ue0HHDTkPfKIem5titibk7YkVYXVDdYC xavxwfLlk7f3PlrzPrF19RnWRGUl5QZ0n914ZFNo0pbT+S9yVFkKMtXvcCHsP/RE f069rFIvJhzGa6gbL+FUkE4SO1SGzV/0xBDgrkUpoezrb23YA4EQKMKFRjPZkraH 0rY3YNrAsKmHzMQlbkWhuhJ0LBoUoAJHle2ZYrk+cT1Gvn7TMH+6RPddwDNNXJrL guAHFdHKljnLqqcbBbcUydoWAMo0YqBbtme+E4GxcSbZiyz/M69eJ46Fyovge/mU pSxRAZChVl3fEACFYsAz42chip4exWHOLvOkODT+CYfVfAeVO5/pNtPi5Y77tJHo KKpDAsB/5XUkCRL9orhpo/g7noix1WUmZLFUPOgL6FWb6D6IHkZwX9f86BoFgvW0 E30rRaSF4l1tATF723AEYKFG41a10iLCkaojy5s+jFPNP77qdvHoHQqtUSjAJyNz bpdEOKt/SLvr4rEYkGf1IJ4Pwvf5nS1yPpahY17dYHwNnHh/ngWCAy18A1to+ACg rNiOw17mJkIe3vBydiy3X7xAq7DPrA39cpRAHoSij1tqPm6mNrpx89WqtfbLWMtY y7k/agDt/WWtUdC/cYmC =X75u -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2015-12-17' into staging QAPI patches for 2015-12-17 # gpg: Signature made Thu 17 Dec 2015 07:33:41 GMT using RSA key ID EB918653 # gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" # gpg: aka "Markus Armbruster <armbru@pond.sub.org>" * remotes/armbru/tags/pull-qapi-2015-12-17: (40 commits) qapi: Detect base class loops qapi: Move duplicate collision checks to schema check() qapi: Enforce (or whitelist) case conventions on qapi members qapi: Track enum values by QAPISchemaMember, not string qapi: Prepare new QAPISchemaMember base class qapi: Shorter visits of optional fields qapi: Simplify visits of optional fields qapi: Fix alternates that accept 'number' but not 'int' qapi: Inline _make_implicit_tag() qapi-types: Drop unnedeed ._fwdefn qapi: Simplify visiting of alternate types qapi: Convert QType into QAPI built-in enum type qobject: Rename qtype_code to QType qobject: Simplify QObject qapi: Change munging of CamelCase enum values qapi: Add alias for ErrorClass cpu: Convert CpuInfo into flat union qapi: Remove obsolete tests for MAX collision qapi: Don't let implicit enum MAX member collide qapi: Tighten the regex on valid names ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
c1a5f950cd
2
block.c
2
block.c
@ -2851,7 +2851,7 @@ ImageInfoSpecific *bdrv_get_specific_info(BlockDriverState *bs)
|
|||||||
return NULL;
|
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) {
|
if (!bs || !bs->drv || !bs->drv->bdrv_debug_event) {
|
||||||
return;
|
return;
|
||||||
|
@ -36,7 +36,7 @@ typedef struct BDRVBlkdebugState {
|
|||||||
int state;
|
int state;
|
||||||
int new_state;
|
int new_state;
|
||||||
|
|
||||||
QLIST_HEAD(, BlkdebugRule) rules[BLKDBG_EVENT_MAX];
|
QLIST_HEAD(, BlkdebugRule) rules[BLKDBG__MAX];
|
||||||
QSIMPLEQ_HEAD(, BlkdebugRule) active_rules;
|
QSIMPLEQ_HEAD(, BlkdebugRule) active_rules;
|
||||||
QLIST_HEAD(, BlkdebugSuspendedReq) suspended_reqs;
|
QLIST_HEAD(, BlkdebugSuspendedReq) suspended_reqs;
|
||||||
} BDRVBlkdebugState;
|
} BDRVBlkdebugState;
|
||||||
@ -64,7 +64,7 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
typedef struct BlkdebugRule {
|
typedef struct BlkdebugRule {
|
||||||
BlkDebugEvent event;
|
BlkdebugEvent event;
|
||||||
int action;
|
int action;
|
||||||
int state;
|
int state;
|
||||||
union {
|
union {
|
||||||
@ -143,69 +143,12 @@ static QemuOptsList *config_groups[] = {
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *event_names[BLKDBG_EVENT_MAX] = {
|
static int get_event_by_name(const char *name, BlkdebugEvent *event)
|
||||||
[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)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < BLKDBG_EVENT_MAX; i++) {
|
for (i = 0; i < BLKDBG__MAX; i++) {
|
||||||
if (!strcmp(event_names[i], name)) {
|
if (!strcmp(BlkdebugEvent_lookup[i], name)) {
|
||||||
*event = i;
|
*event = i;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -224,7 +167,7 @@ static int add_rule(void *opaque, QemuOpts *opts, Error **errp)
|
|||||||
struct add_rule_data *d = opaque;
|
struct add_rule_data *d = opaque;
|
||||||
BDRVBlkdebugState *s = d->s;
|
BDRVBlkdebugState *s = d->s;
|
||||||
const char* event_name;
|
const char* event_name;
|
||||||
BlkDebugEvent event;
|
BlkdebugEvent event;
|
||||||
struct BlkdebugRule *rule;
|
struct BlkdebugRule *rule;
|
||||||
|
|
||||||
/* Find the right event for the rule */
|
/* Find the right event for the rule */
|
||||||
@ -564,7 +507,7 @@ static void blkdebug_close(BlockDriverState *bs)
|
|||||||
BlkdebugRule *rule, *next;
|
BlkdebugRule *rule, *next;
|
||||||
int i;
|
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) {
|
QLIST_FOREACH_SAFE(rule, &s->rules[i], next, next) {
|
||||||
remove_rule(rule);
|
remove_rule(rule);
|
||||||
}
|
}
|
||||||
@ -627,13 +570,13 @@ static bool process_rule(BlockDriverState *bs, struct BlkdebugRule *rule,
|
|||||||
return injected;
|
return injected;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void blkdebug_debug_event(BlockDriverState *bs, BlkDebugEvent event)
|
static void blkdebug_debug_event(BlockDriverState *bs, BlkdebugEvent event)
|
||||||
{
|
{
|
||||||
BDRVBlkdebugState *s = bs->opaque;
|
BDRVBlkdebugState *s = bs->opaque;
|
||||||
struct BlkdebugRule *rule, *next;
|
struct BlkdebugRule *rule, *next;
|
||||||
bool injected;
|
bool injected;
|
||||||
|
|
||||||
assert((int)event >= 0 && event < BLKDBG_EVENT_MAX);
|
assert((int)event >= 0 && event < BLKDBG__MAX);
|
||||||
|
|
||||||
injected = false;
|
injected = false;
|
||||||
s->new_state = s->state;
|
s->new_state = s->state;
|
||||||
@ -648,7 +591,7 @@ static int blkdebug_debug_breakpoint(BlockDriverState *bs, const char *event,
|
|||||||
{
|
{
|
||||||
BDRVBlkdebugState *s = bs->opaque;
|
BDRVBlkdebugState *s = bs->opaque;
|
||||||
struct BlkdebugRule *rule;
|
struct BlkdebugRule *rule;
|
||||||
BlkDebugEvent blkdebug_event;
|
BlkdebugEvent blkdebug_event;
|
||||||
|
|
||||||
if (get_event_by_name(event, &blkdebug_event) < 0) {
|
if (get_event_by_name(event, &blkdebug_event) < 0) {
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
@ -690,7 +633,7 @@ static int blkdebug_debug_remove_breakpoint(BlockDriverState *bs,
|
|||||||
BlkdebugRule *rule, *next;
|
BlkdebugRule *rule, *next;
|
||||||
int i, ret = -ENOENT;
|
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) {
|
QLIST_FOREACH_SAFE(rule, &s->rules[i], next, next) {
|
||||||
if (rule->action == ACTION_SUSPEND &&
|
if (rule->action == ACTION_SUSPEND &&
|
||||||
!strcmp(rule->options.suspend.tag, tag)) {
|
!strcmp(rule->options.suspend.tag, tag)) {
|
||||||
|
@ -61,7 +61,7 @@ typedef struct ParallelsHeader {
|
|||||||
typedef enum ParallelsPreallocMode {
|
typedef enum ParallelsPreallocMode {
|
||||||
PRL_PREALLOC_MODE_FALLOCATE = 0,
|
PRL_PREALLOC_MODE_FALLOCATE = 0,
|
||||||
PRL_PREALLOC_MODE_TRUNCATE = 1,
|
PRL_PREALLOC_MODE_TRUNCATE = 1,
|
||||||
PRL_PREALLOC_MODE_MAX = 2,
|
PRL_PREALLOC_MODE__MAX = 2,
|
||||||
} ParallelsPreallocMode;
|
} ParallelsPreallocMode;
|
||||||
|
|
||||||
static const char *prealloc_mode_lookup[] = {
|
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);
|
s->prealloc_size = MAX(s->tracks, s->prealloc_size >> BDRV_SECTOR_BITS);
|
||||||
buf = qemu_opt_get_del(opts, PARALLELS_OPT_PREALLOC_MODE);
|
buf = qemu_opt_get_del(opts, PARALLELS_OPT_PREALLOC_MODE);
|
||||||
s->prealloc_mode = qapi_enum_parse(prealloc_mode_lookup, buf,
|
s->prealloc_mode = qapi_enum_parse(prealloc_mode_lookup, buf,
|
||||||
PRL_PREALLOC_MODE_MAX, PRL_PREALLOC_MODE_FALLOCATE, &local_err);
|
PRL_PREALLOC_MODE__MAX, PRL_PREALLOC_MODE_FALLOCATE, &local_err);
|
||||||
g_free(buf);
|
g_free(buf);
|
||||||
if (local_err != NULL) {
|
if (local_err != NULL) {
|
||||||
goto fail_options;
|
goto fail_options;
|
||||||
|
@ -588,7 +588,7 @@ static void dump_qlist(fprintf_function func_fprintf, void *f, int indentation,
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
for (entry = qlist_first(list); entry; entry = qlist_next(entry), i++) {
|
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);
|
bool composite = (type == QTYPE_QDICT || type == QTYPE_QLIST);
|
||||||
const char *format = composite ? "%*s[%i]:\n" : "%*s[%i]: ";
|
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;
|
const QDictEntry *entry;
|
||||||
|
|
||||||
for (entry = qdict_first(dict); entry; entry = qdict_next(dict, 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);
|
bool composite = (type == QTYPE_QDICT || type == QTYPE_QLIST);
|
||||||
const char *format = composite ? "%*s%s:\n" : "%*s%s: ";
|
const char *format = composite ? "%*s%s:\n" : "%*s%s: ";
|
||||||
char key[strlen(entry->key) + 1];
|
char key[strlen(entry->key) + 1];
|
||||||
|
@ -2269,7 +2269,7 @@ static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp)
|
|||||||
DEFAULT_CLUSTER_SIZE);
|
DEFAULT_CLUSTER_SIZE);
|
||||||
buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
|
buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
|
||||||
prealloc = qapi_enum_parse(PreallocMode_lookup, buf,
|
prealloc = qapi_enum_parse(PreallocMode_lookup, buf,
|
||||||
PREALLOC_MODE_MAX, PREALLOC_MODE_OFF,
|
PREALLOC_MODE__MAX, PREALLOC_MODE_OFF,
|
||||||
&local_err);
|
&local_err);
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
error_propagate(errp, local_err);
|
error_propagate(errp, local_err);
|
||||||
|
@ -847,7 +847,7 @@ static int parse_read_pattern(const char *opt)
|
|||||||
return QUORUM_READ_PATTERN_QUORUM;
|
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])) {
|
if (!strcmp(opt, QuorumReadPattern_lookup[i])) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
nocow = qemu_opt_get_bool(opts, BLOCK_OPT_NOCOW, false);
|
||||||
buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
|
buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
|
||||||
prealloc = qapi_enum_parse(PreallocMode_lookup, buf,
|
prealloc = qapi_enum_parse(PreallocMode_lookup, buf,
|
||||||
PREALLOC_MODE_MAX, PREALLOC_MODE_OFF,
|
PREALLOC_MODE__MAX, PREALLOC_MODE_OFF,
|
||||||
&local_err);
|
&local_err);
|
||||||
g_free(buf);
|
g_free(buf);
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
|
@ -454,7 +454,7 @@ static void extract_common_blockdev_options(QemuOpts *opts, int *bdrv_flags,
|
|||||||
*detect_zeroes =
|
*detect_zeroes =
|
||||||
qapi_enum_parse(BlockdevDetectZeroesOptions_lookup,
|
qapi_enum_parse(BlockdevDetectZeroesOptions_lookup,
|
||||||
qemu_opt_get(opts, "detect-zeroes"),
|
qemu_opt_get(opts, "detect-zeroes"),
|
||||||
BLOCKDEV_DETECT_ZEROES_OPTIONS_MAX,
|
BLOCKDEV_DETECT_ZEROES_OPTIONS__MAX,
|
||||||
BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF,
|
BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF,
|
||||||
&local_error);
|
&local_error);
|
||||||
if (local_error) {
|
if (local_error) {
|
||||||
|
31
cpus.c
31
cpus.c
@ -1558,22 +1558,29 @@ CpuInfoList *qmp_query_cpus(Error **errp)
|
|||||||
info->value->qom_path = object_get_canonical_path(OBJECT(cpu));
|
info->value->qom_path = object_get_canonical_path(OBJECT(cpu));
|
||||||
info->value->thread_id = cpu->thread_id;
|
info->value->thread_id = cpu->thread_id;
|
||||||
#if defined(TARGET_I386)
|
#if defined(TARGET_I386)
|
||||||
info->value->has_pc = true;
|
info->value->arch = CPU_INFO_ARCH_X86;
|
||||||
info->value->pc = env->eip + env->segs[R_CS].base;
|
info->value->u.x86 = g_new0(CpuInfoX86, 1);
|
||||||
|
info->value->u.x86->pc = env->eip + env->segs[R_CS].base;
|
||||||
#elif defined(TARGET_PPC)
|
#elif defined(TARGET_PPC)
|
||||||
info->value->has_nip = true;
|
info->value->arch = CPU_INFO_ARCH_PPC;
|
||||||
info->value->nip = env->nip;
|
info->value->u.ppc = g_new0(CpuInfoPPC, 1);
|
||||||
|
info->value->u.ppc->nip = env->nip;
|
||||||
#elif defined(TARGET_SPARC)
|
#elif defined(TARGET_SPARC)
|
||||||
info->value->has_pc = true;
|
info->value->arch = CPU_INFO_ARCH_SPARC;
|
||||||
info->value->pc = env->pc;
|
info->value->u.sparc = g_new0(CpuInfoSPARC, 1);
|
||||||
info->value->has_npc = true;
|
info->value->u.sparc->pc = env->pc;
|
||||||
info->value->npc = env->npc;
|
info->value->u.sparc->npc = env->npc;
|
||||||
#elif defined(TARGET_MIPS)
|
#elif defined(TARGET_MIPS)
|
||||||
info->value->has_PC = true;
|
info->value->arch = CPU_INFO_ARCH_MIPS;
|
||||||
info->value->PC = env->active_tc.PC;
|
info->value->u.mips = g_new0(CpuInfoMIPS, 1);
|
||||||
|
info->value->u.mips->PC = env->active_tc.PC;
|
||||||
#elif defined(TARGET_TRICORE)
|
#elif defined(TARGET_TRICORE)
|
||||||
info->value->has_PC = true;
|
info->value->arch = CPU_INFO_ARCH_TRICORE;
|
||||||
info->value->PC = env->PC;
|
info->value->u.tricore = g_new0(CpuInfoTricore, 1);
|
||||||
|
info->value->u.tricore->PC = env->PC;
|
||||||
|
#else
|
||||||
|
info->value->arch = CPU_INFO_ARCH_OTHER;
|
||||||
|
info->value->u.other = g_new0(CpuInfoOther, 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* XXX: waiting for the qapi to support GSList */
|
/* XXX: waiting for the qapi to support GSList */
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
Block I/O error injection using blkdebug
|
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
|
This work is licensed under the terms of the GNU GPL, version 2 or later. See
|
||||||
the COPYING file in the top-level directory.
|
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
|
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
|
See qapi/block-core.json:BlkdebugEvent for the full list of events.
|
||||||
to grep block driver source code to understand the meaning of specific events.
|
You may need to grep block driver source code to understand the
|
||||||
|
meaning of specific events.
|
||||||
|
|
||||||
State transitions
|
State transitions
|
||||||
-----------------
|
-----------------
|
||||||
|
@ -118,17 +118,17 @@ tracking optional fields.
|
|||||||
|
|
||||||
Any name (command, event, type, field, or enum value) beginning with
|
Any name (command, event, type, field, or enum value) beginning with
|
||||||
"x-" is marked experimental, and may be withdrawn or changed
|
"x-" is marked experimental, and may be withdrawn or changed
|
||||||
incompatibly in a future release. Downstream vendors may add
|
incompatibly in a future release. All names must begin with a letter,
|
||||||
extensions; such extensions should begin with a prefix matching
|
and contain only ASCII letters, digits, dash, and underscore. There
|
||||||
"__RFQDN_" (for the reverse-fully-qualified-domain-name of the
|
are two exceptions: enum values may start with a digit, and any
|
||||||
vendor), even if the rest of the name uses dash (example:
|
extensions added by downstream vendors should start with a prefix
|
||||||
__com.redhat_drive-mirror). Other than downstream extensions (with
|
matching "__RFQDN_" (for the reverse-fully-qualified-domain-name of
|
||||||
leading underscore and the use of dots), all names should begin with a
|
the vendor), even if the rest of the name uses dash (example:
|
||||||
letter, and contain only ASCII letters, digits, dash, and underscore.
|
__com.redhat_drive-mirror). Names beginning with 'q_' are reserved
|
||||||
Names beginning with 'q_' are reserved for the generator: QMP names
|
for the generator: QMP names that resemble C keywords or other
|
||||||
that resemble C keywords or other problematic strings will be munged
|
problematic strings will be munged in C to use this prefix. For
|
||||||
in C to use this prefix. For example, a field named "default" in
|
example, a field named "default" in qapi becomes "q_default" in the
|
||||||
qapi becomes "q_default" in the generated C code.
|
generated C code.
|
||||||
|
|
||||||
In the rest of this document, usage lines are given for each
|
In the rest of this document, usage lines are given for each
|
||||||
expression type, with literal strings written in lower case and
|
expression type, with literal strings written in lower case and
|
||||||
@ -160,6 +160,7 @@ The following types are predefined, and map to C as follows:
|
|||||||
accepts size suffixes
|
accepts size suffixes
|
||||||
bool bool JSON true or false
|
bool bool JSON true or false
|
||||||
any QObject * any JSON value
|
any QObject * any JSON value
|
||||||
|
QType QType JSON string matching enum QType values
|
||||||
|
|
||||||
|
|
||||||
=== Includes ===
|
=== Includes ===
|
||||||
@ -383,9 +384,6 @@ where each branch of the union names a QAPI type. For example:
|
|||||||
'data': { 'definition': 'BlockdevOptions',
|
'data': { 'definition': 'BlockdevOptions',
|
||||||
'reference': 'str' } }
|
'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
|
Unlike a union, the discriminator string is never passed on the wire
|
||||||
for the Client JSON Protocol. Instead, the value's JSON type serves
|
for the Client JSON Protocol. Instead, the value's JSON type serves
|
||||||
as an implicit discriminator, which in turn means that an alternate
|
as an implicit discriminator, which in turn means that an alternate
|
||||||
@ -1053,7 +1051,7 @@ Example:
|
|||||||
|
|
||||||
const char *const example_QAPIEvent_lookup[] = {
|
const char *const example_QAPIEvent_lookup[] = {
|
||||||
[EXAMPLE_QAPI_EVENT_MY_EVENT] = "MY_EVENT",
|
[EXAMPLE_QAPI_EVENT_MY_EVENT] = "MY_EVENT",
|
||||||
[EXAMPLE_QAPI_EVENT_MAX] = NULL,
|
[EXAMPLE_QAPI_EVENT__MAX] = NULL,
|
||||||
};
|
};
|
||||||
$ cat qapi-generated/example-qapi-event.h
|
$ cat qapi-generated/example-qapi-event.h
|
||||||
[Uninteresting stuff omitted...]
|
[Uninteresting stuff omitted...]
|
||||||
@ -1070,7 +1068,7 @@ Example:
|
|||||||
|
|
||||||
typedef enum example_QAPIEvent {
|
typedef enum example_QAPIEvent {
|
||||||
EXAMPLE_QAPI_EVENT_MY_EVENT = 0,
|
EXAMPLE_QAPI_EVENT_MY_EVENT = 0,
|
||||||
EXAMPLE_QAPI_EVENT_MAX = 1,
|
EXAMPLE_QAPI_EVENT__MAX = 1,
|
||||||
} example_QAPIEvent;
|
} example_QAPIEvent;
|
||||||
|
|
||||||
extern const char *const example_QAPIEvent_lookup[];
|
extern const char *const example_QAPIEvent_lookup[];
|
||||||
|
44
hmp.c
44
hmp.c
@ -311,17 +311,25 @@ void hmp_info_cpus(Monitor *mon, const QDict *qdict)
|
|||||||
|
|
||||||
monitor_printf(mon, "%c CPU #%" PRId64 ":", active, cpu->value->CPU);
|
monitor_printf(mon, "%c CPU #%" PRId64 ":", active, cpu->value->CPU);
|
||||||
|
|
||||||
if (cpu->value->has_pc) {
|
switch (cpu->value->arch) {
|
||||||
monitor_printf(mon, " pc=0x%016" PRIx64, cpu->value->pc);
|
case CPU_INFO_ARCH_X86:
|
||||||
}
|
monitor_printf(mon, " pc=0x%016" PRIx64, cpu->value->u.x86->pc);
|
||||||
if (cpu->value->has_nip) {
|
break;
|
||||||
monitor_printf(mon, " nip=0x%016" PRIx64, cpu->value->nip);
|
case CPU_INFO_ARCH_PPC:
|
||||||
}
|
monitor_printf(mon, " nip=0x%016" PRIx64, cpu->value->u.ppc->nip);
|
||||||
if (cpu->value->has_npc) {
|
break;
|
||||||
monitor_printf(mon, " npc=0x%016" PRIx64, cpu->value->npc);
|
case CPU_INFO_ARCH_SPARC:
|
||||||
}
|
monitor_printf(mon, " pc=0x%016" PRIx64, cpu->value->u.sparc->pc);
|
||||||
if (cpu->value->has_PC) {
|
monitor_printf(mon, " npc=0x%016" PRIx64, cpu->value->u.sparc->npc);
|
||||||
monitor_printf(mon, " PC=0x%016" PRIx64, cpu->value->PC);
|
break;
|
||||||
|
case CPU_INFO_ARCH_MIPS:
|
||||||
|
monitor_printf(mon, " PC=0x%016" PRIx64, cpu->value->u.mips->PC);
|
||||||
|
break;
|
||||||
|
case CPU_INFO_ARCH_TRICORE:
|
||||||
|
monitor_printf(mon, " PC=0x%016" PRIx64, cpu->value->u.tricore->PC);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cpu->value->halted) {
|
if (cpu->value->halted) {
|
||||||
@ -855,7 +863,7 @@ void hmp_info_tpm(Monitor *mon, const QDict *qdict)
|
|||||||
tpo->has_cancel_path ? ",cancel-path=" : "",
|
tpo->has_cancel_path ? ",cancel-path=" : "",
|
||||||
tpo->has_cancel_path ? tpo->cancel_path : "");
|
tpo->has_cancel_path ? tpo->cancel_path : "");
|
||||||
break;
|
break;
|
||||||
case TPM_TYPE_OPTIONS_KIND_MAX:
|
case TPM_TYPE_OPTIONS_KIND__MAX:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
monitor_printf(mon, "\n");
|
monitor_printf(mon, "\n");
|
||||||
@ -1203,7 +1211,7 @@ void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict)
|
|||||||
MigrationCapabilityStatusList *caps = g_malloc0(sizeof(*caps));
|
MigrationCapabilityStatusList *caps = g_malloc0(sizeof(*caps));
|
||||||
int i;
|
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) {
|
if (strcmp(cap, MigrationCapability_lookup[i]) == 0) {
|
||||||
caps->value = g_malloc0(sizeof(*caps->value));
|
caps->value = g_malloc0(sizeof(*caps->value));
|
||||||
caps->value->capability = i;
|
caps->value->capability = i;
|
||||||
@ -1214,7 +1222,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);
|
error_setg(&err, QERR_INVALID_PARAMETER, cap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1239,7 +1247,7 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
|
|||||||
bool has_x_cpu_throttle_increment = false;
|
bool has_x_cpu_throttle_increment = false;
|
||||||
int i;
|
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) {
|
if (strcmp(param, MigrationParameter_lookup[i]) == 0) {
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case MIGRATION_PARAMETER_COMPRESS_LEVEL:
|
case MIGRATION_PARAMETER_COMPRESS_LEVEL:
|
||||||
@ -1268,7 +1276,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);
|
error_setg(&err, QERR_INVALID_PARAMETER, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1368,7 +1376,7 @@ void hmp_change(Monitor *mon, const QDict *qdict)
|
|||||||
if (read_only) {
|
if (read_only) {
|
||||||
read_only_mode =
|
read_only_mode =
|
||||||
qapi_enum_parse(BlockdevChangeReadOnlyMode_lookup,
|
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);
|
BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN, &err);
|
||||||
if (err) {
|
if (err) {
|
||||||
hmp_handle_error(mon, &err);
|
hmp_handle_error(mon, &err);
|
||||||
@ -1771,7 +1779,7 @@ void hmp_sendkey(Monitor *mon, const QDict *qdict)
|
|||||||
keylist->value->u.number = value;
|
keylist->value->u.number = value;
|
||||||
} else {
|
} else {
|
||||||
int idx = index_from_key(keyname_buf);
|
int idx = index_from_key(keyname_buf);
|
||||||
if (idx == Q_KEY_CODE_MAX) {
|
if (idx == Q_KEY_CODE__MAX) {
|
||||||
goto err_out;
|
goto err_out;
|
||||||
}
|
}
|
||||||
keylist->value->type = KEY_VALUE_KIND_QCODE;
|
keylist->value->type = KEY_VALUE_KIND_QCODE;
|
||||||
|
@ -714,7 +714,7 @@ MemoryRegion *escc_init(hwaddr base, qemu_irq irqA, qemu_irq irqB,
|
|||||||
return &d->mmio;
|
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] = 99,
|
||||||
[Q_KEY_CODE_SHIFT_R] = 110,
|
[Q_KEY_CODE_SHIFT_R] = 110,
|
||||||
[Q_KEY_CODE_ALT] = 19,
|
[Q_KEY_CODE_ALT] = 19,
|
||||||
|
@ -225,7 +225,7 @@ static void pc_init1(MachineState *machine,
|
|||||||
|
|
||||||
pc_vga_init(isa_bus, pci_enabled ? pci_bus : NULL);
|
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) {
|
if (pcms->vmport == ON_OFF_AUTO_AUTO) {
|
||||||
pcms->vmport = xen_enabled() ? ON_OFF_AUTO_OFF : ON_OFF_AUTO_ON;
|
pcms->vmport = xen_enabled() ? ON_OFF_AUTO_OFF : ON_OFF_AUTO_ON;
|
||||||
}
|
}
|
||||||
|
@ -233,7 +233,7 @@ static void pc_q35_init(MachineState *machine)
|
|||||||
|
|
||||||
pc_register_ferr_irq(gsi[13]);
|
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) {
|
if (pcms->vmport == ON_OFF_AUTO_AUTO) {
|
||||||
pcms->vmport = xen_enabled() ? ON_OFF_AUTO_OFF : ON_OFF_AUTO_ON;
|
pcms->vmport = xen_enabled() ? ON_OFF_AUTO_OFF : ON_OFF_AUTO_ON;
|
||||||
}
|
}
|
||||||
|
@ -108,7 +108,7 @@ void hid_set_next_idle(HIDState *hs)
|
|||||||
static void hid_pointer_event(DeviceState *dev, QemuConsole *src,
|
static void hid_pointer_event(DeviceState *dev, QemuConsole *src,
|
||||||
InputEvent *evt)
|
InputEvent *evt)
|
||||||
{
|
{
|
||||||
static const int bmap[INPUT_BUTTON_MAX] = {
|
static const int bmap[INPUT_BUTTON__MAX] = {
|
||||||
[INPUT_BUTTON_LEFT] = 0x01,
|
[INPUT_BUTTON_LEFT] = 0x01,
|
||||||
[INPUT_BUTTON_RIGHT] = 0x02,
|
[INPUT_BUTTON_RIGHT] = 0x02,
|
||||||
[INPUT_BUTTON_MIDDLE] = 0x04,
|
[INPUT_BUTTON_MIDDLE] = 0x04,
|
||||||
@ -139,9 +139,9 @@ static void hid_pointer_event(DeviceState *dev, QemuConsole *src,
|
|||||||
case INPUT_EVENT_KIND_BTN:
|
case INPUT_EVENT_KIND_BTN:
|
||||||
if (evt->u.btn->down) {
|
if (evt->u.btn->down) {
|
||||||
e->buttons_state |= bmap[evt->u.btn->button];
|
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--;
|
e->dz--;
|
||||||
} else if (evt->u.btn->button == INPUT_BUTTON_WHEEL_DOWN) {
|
} else if (evt->u.btn->button == INPUT_BUTTON_WHEELDOWN) {
|
||||||
e->dz++;
|
e->dz++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -382,7 +382,7 @@ static void ps2_mouse_send_packet(PS2MouseState *s)
|
|||||||
static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,
|
static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,
|
||||||
InputEvent *evt)
|
InputEvent *evt)
|
||||||
{
|
{
|
||||||
static const int bmap[INPUT_BUTTON_MAX] = {
|
static const int bmap[INPUT_BUTTON__MAX] = {
|
||||||
[INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON,
|
[INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON,
|
||||||
[INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON,
|
[INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON,
|
||||||
[INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON,
|
[INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON,
|
||||||
@ -405,9 +405,9 @@ static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,
|
|||||||
case INPUT_EVENT_KIND_BTN:
|
case INPUT_EVENT_KIND_BTN:
|
||||||
if (evt->u.btn->down) {
|
if (evt->u.btn->down) {
|
||||||
s->mouse_buttons |= bmap[evt->u.btn->button];
|
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--;
|
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++;
|
s->mouse_dz++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -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_ESC] = KEY_ESC,
|
||||||
[Q_KEY_CODE_1] = KEY_1,
|
[Q_KEY_CODE_1] = KEY_1,
|
||||||
[Q_KEY_CODE_2] = KEY_2,
|
[Q_KEY_CODE_2] = KEY_2,
|
||||||
@ -138,20 +138,20 @@ static const unsigned int keymap_qcode[Q_KEY_CODE_MAX] = {
|
|||||||
[Q_KEY_CODE_MENU] = KEY_MENU,
|
[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_LEFT] = BTN_LEFT,
|
||||||
[INPUT_BUTTON_RIGHT] = BTN_RIGHT,
|
[INPUT_BUTTON_RIGHT] = BTN_RIGHT,
|
||||||
[INPUT_BUTTON_MIDDLE] = BTN_MIDDLE,
|
[INPUT_BUTTON_MIDDLE] = BTN_MIDDLE,
|
||||||
[INPUT_BUTTON_WHEEL_UP] = BTN_GEAR_UP,
|
[INPUT_BUTTON_WHEELUP] = BTN_GEAR_UP,
|
||||||
[INPUT_BUTTON_WHEEL_DOWN] = BTN_GEAR_DOWN,
|
[INPUT_BUTTON_WHEELDOWN] = 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_X] = REL_X,
|
||||||
[INPUT_AXIS_Y] = REL_Y,
|
[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_X] = ABS_X,
|
||||||
[INPUT_AXIS_Y] = ABS_Y,
|
[INPUT_AXIS_Y] = ABS_Y,
|
||||||
};
|
};
|
||||||
|
@ -520,66 +520,6 @@ void bdrv_op_block_all(BlockDriverState *bs, Error *reason);
|
|||||||
void bdrv_op_unblock_all(BlockDriverState *bs, Error *reason);
|
void bdrv_op_unblock_all(BlockDriverState *bs, Error *reason);
|
||||||
bool bdrv_op_blocker_is_empty(BlockDriverState *bs);
|
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) \
|
#define BLKDBG_EVENT(child, evt) \
|
||||||
do { \
|
do { \
|
||||||
if (child) { \
|
if (child) { \
|
||||||
@ -587,7 +527,7 @@ typedef enum {
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} 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,
|
int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event,
|
||||||
const char *tag);
|
const char *tag);
|
||||||
|
@ -244,7 +244,7 @@ struct BlockDriver {
|
|||||||
int (*bdrv_amend_options)(BlockDriverState *bs, QemuOpts *opts,
|
int (*bdrv_amend_options)(BlockDriverState *bs, QemuOpts *opts,
|
||||||
BlockDriverAmendStatusCB *status_cb);
|
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? */
|
/* TODO Better pass a option string/QDict/QemuOpts to add any rule? */
|
||||||
int (*bdrv_debug_breakpoint)(BlockDriverState *bs, const char *event,
|
int (*bdrv_debug_breakpoint)(BlockDriverState *bs, const char *event,
|
||||||
|
@ -239,7 +239,7 @@ struct Property {
|
|||||||
PropertyInfo *info;
|
PropertyInfo *info;
|
||||||
ptrdiff_t offset;
|
ptrdiff_t offset;
|
||||||
uint8_t bitnr;
|
uint8_t bitnr;
|
||||||
qtype_code qtype;
|
QType qtype;
|
||||||
int64_t defval;
|
int64_t defval;
|
||||||
int arrayoffset;
|
int arrayoffset;
|
||||||
PropertyInfo *arrayinfo;
|
PropertyInfo *arrayinfo;
|
||||||
|
@ -133,7 +133,7 @@ struct MigrationState
|
|||||||
QemuThread thread;
|
QemuThread thread;
|
||||||
QEMUBH *cleanup_bh;
|
QEMUBH *cleanup_bh;
|
||||||
QEMUFile *file;
|
QEMUFile *file;
|
||||||
int parameters[MIGRATION_PARAMETER_MAX];
|
int parameters[MIGRATION_PARAMETER__MAX];
|
||||||
|
|
||||||
int state;
|
int state;
|
||||||
MigrationParams params;
|
MigrationParams params;
|
||||||
@ -151,7 +151,7 @@ struct MigrationState
|
|||||||
int64_t expected_downtime;
|
int64_t expected_downtime;
|
||||||
int64_t dirty_pages_rate;
|
int64_t dirty_pages_rate;
|
||||||
int64_t dirty_bytes_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 xbzrle_cache_size;
|
||||||
int64_t setup_time;
|
int64_t setup_time;
|
||||||
int64_t dirty_sync_count;
|
int64_t dirty_sync_count;
|
||||||
|
@ -90,6 +90,20 @@
|
|||||||
*/
|
*/
|
||||||
typedef struct Error Error;
|
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_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;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get @err's human-readable error message.
|
* Get @err's human-readable error message.
|
||||||
*/
|
*/
|
||||||
|
@ -25,5 +25,6 @@ typedef struct QBool {
|
|||||||
QBool *qbool_from_bool(bool value);
|
QBool *qbool_from_bool(bool value);
|
||||||
bool qbool_get_bool(const QBool *qb);
|
bool qbool_get_bool(const QBool *qb);
|
||||||
QBool *qobject_to_qbool(const QObject *obj);
|
QBool *qobject_to_qbool(const QObject *obj);
|
||||||
|
void qbool_destroy_obj(QObject *obj);
|
||||||
|
|
||||||
#endif /* QBOOL_H */
|
#endif /* QBOOL_H */
|
||||||
|
@ -48,6 +48,7 @@ void qdict_iter(const QDict *qdict,
|
|||||||
void *opaque);
|
void *opaque);
|
||||||
const QDictEntry *qdict_first(const QDict *qdict);
|
const QDictEntry *qdict_first(const QDict *qdict);
|
||||||
const QDictEntry *qdict_next(const QDict *qdict, const QDictEntry *entry);
|
const QDictEntry *qdict_next(const QDict *qdict, const QDictEntry *entry);
|
||||||
|
void qdict_destroy_obj(QObject *obj);
|
||||||
|
|
||||||
/* Helper to qdict_put_obj(), accepts any object */
|
/* Helper to qdict_put_obj(), accepts any object */
|
||||||
#define qdict_put(qdict, key, obj) \
|
#define qdict_put(qdict, key, obj) \
|
||||||
|
@ -25,5 +25,6 @@ typedef struct QFloat {
|
|||||||
QFloat *qfloat_from_double(double value);
|
QFloat *qfloat_from_double(double value);
|
||||||
double qfloat_get_double(const QFloat *qi);
|
double qfloat_get_double(const QFloat *qi);
|
||||||
QFloat *qobject_to_qfloat(const QObject *obj);
|
QFloat *qobject_to_qfloat(const QObject *obj);
|
||||||
|
void qfloat_destroy_obj(QObject *obj);
|
||||||
|
|
||||||
#endif /* QFLOAT_H */
|
#endif /* QFLOAT_H */
|
||||||
|
@ -24,5 +24,6 @@ typedef struct QInt {
|
|||||||
QInt *qint_from_int(int64_t value);
|
QInt *qint_from_int(int64_t value);
|
||||||
int64_t qint_get_int(const QInt *qi);
|
int64_t qint_get_int(const QInt *qi);
|
||||||
QInt *qobject_to_qint(const QObject *obj);
|
QInt *qobject_to_qint(const QObject *obj);
|
||||||
|
void qint_destroy_obj(QObject *obj);
|
||||||
|
|
||||||
#endif /* QINT_H */
|
#endif /* QINT_H */
|
||||||
|
@ -49,6 +49,7 @@ QObject *qlist_peek(QList *qlist);
|
|||||||
int qlist_empty(const QList *qlist);
|
int qlist_empty(const QList *qlist);
|
||||||
size_t qlist_size(const QList *qlist);
|
size_t qlist_size(const QList *qlist);
|
||||||
QList *qobject_to_qlist(const QObject *obj);
|
QList *qobject_to_qlist(const QObject *obj);
|
||||||
|
void qlist_destroy_obj(QObject *obj);
|
||||||
|
|
||||||
static inline const QListEntry *qlist_first(const QList *qlist)
|
static inline const QListEntry *qlist_first(const QList *qlist)
|
||||||
{
|
{
|
||||||
|
@ -34,30 +34,12 @@
|
|||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include "qapi-types.h"
|
||||||
|
|
||||||
typedef enum {
|
struct QObject {
|
||||||
QTYPE_NONE, /* sentinel value, no QObject has this type code */
|
QType type;
|
||||||
QTYPE_QNULL,
|
|
||||||
QTYPE_QINT,
|
|
||||||
QTYPE_QSTRING,
|
|
||||||
QTYPE_QDICT,
|
|
||||||
QTYPE_QLIST,
|
|
||||||
QTYPE_QFLOAT,
|
|
||||||
QTYPE_QBOOL,
|
|
||||||
QTYPE_MAX,
|
|
||||||
} qtype_code;
|
|
||||||
|
|
||||||
struct QObject;
|
|
||||||
|
|
||||||
typedef struct QType {
|
|
||||||
qtype_code code;
|
|
||||||
void (*destroy)(struct QObject *);
|
|
||||||
} QType;
|
|
||||||
|
|
||||||
typedef struct QObject {
|
|
||||||
const QType *type;
|
|
||||||
size_t refcnt;
|
size_t refcnt;
|
||||||
} QObject;
|
};
|
||||||
|
|
||||||
/* Get the 'base' part of an object */
|
/* Get the 'base' part of an object */
|
||||||
#define QOBJECT(obj) (&(obj)->base)
|
#define QOBJECT(obj) (&(obj)->base)
|
||||||
@ -71,9 +53,12 @@ typedef struct QObject {
|
|||||||
qobject_decref(obj ? QOBJECT(obj) : NULL)
|
qobject_decref(obj ? QOBJECT(obj) : NULL)
|
||||||
|
|
||||||
/* Initialize an object to default values */
|
/* Initialize an object to default values */
|
||||||
#define QOBJECT_INIT(obj, qtype_type) \
|
static inline void qobject_init(QObject *obj, QType type)
|
||||||
obj->base.refcnt = 1; \
|
{
|
||||||
obj->base.type = qtype_type
|
assert(QTYPE_NONE < type && type < QTYPE__MAX);
|
||||||
|
obj->refcnt = 1;
|
||||||
|
obj->type = type;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* qobject_incref(): Increment QObject's reference count
|
* qobject_incref(): Increment QObject's reference count
|
||||||
@ -84,6 +69,11 @@ static inline void qobject_incref(QObject *obj)
|
|||||||
obj->refcnt++;
|
obj->refcnt++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qobject_destroy(): Free resources used by the object
|
||||||
|
*/
|
||||||
|
void qobject_destroy(QObject *obj);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* qobject_decref(): Decrement QObject's reference count, deallocate
|
* qobject_decref(): Decrement QObject's reference count, deallocate
|
||||||
* when it reaches zero
|
* when it reaches zero
|
||||||
@ -92,19 +82,17 @@ static inline void qobject_decref(QObject *obj)
|
|||||||
{
|
{
|
||||||
assert(!obj || obj->refcnt);
|
assert(!obj || obj->refcnt);
|
||||||
if (obj && --obj->refcnt == 0) {
|
if (obj && --obj->refcnt == 0) {
|
||||||
assert(obj->type != NULL);
|
qobject_destroy(obj);
|
||||||
assert(obj->type->destroy != NULL);
|
|
||||||
obj->type->destroy(obj);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* qobject_type(): Return the QObject's type
|
* 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(obj->type != NULL);
|
assert(QTYPE_NONE < obj->type && obj->type < QTYPE__MAX);
|
||||||
return obj->type->code;
|
return obj->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern QObject qnull_;
|
extern QObject qnull_;
|
||||||
|
@ -32,5 +32,6 @@ void qstring_append_int(QString *qstring, int64_t value);
|
|||||||
void qstring_append(QString *qstring, const char *str);
|
void qstring_append(QString *qstring, const char *str);
|
||||||
void qstring_append_chr(QString *qstring, int c);
|
void qstring_append_chr(QString *qstring, int c);
|
||||||
QString *qobject_to_qstring(const QObject *obj);
|
QString *qobject_to_qstring(const QObject *obj);
|
||||||
|
void qstring_destroy_obj(QObject *obj);
|
||||||
|
|
||||||
#endif /* QSTRING_H */
|
#endif /* QSTRING_H */
|
||||||
|
@ -32,7 +32,8 @@ struct Visitor
|
|||||||
|
|
||||||
void (*type_enum)(Visitor *v, int *obj, const char * const strings[],
|
void (*type_enum)(Visitor *v, int *obj, const char * const strings[],
|
||||||
const char *kind, const char *name, Error **errp);
|
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, bool promote_int,
|
||||||
const char *name, Error **errp);
|
const char *name, Error **errp);
|
||||||
|
|
||||||
void (*type_int)(Visitor *v, int64_t *obj, const char *name, Error **errp);
|
void (*type_int)(Visitor *v, int64_t *obj, const char *name, Error **errp);
|
||||||
@ -43,9 +44,8 @@ struct Visitor
|
|||||||
void (*type_any)(Visitor *v, QObject **obj, const char *name,
|
void (*type_any)(Visitor *v, QObject **obj, const char *name,
|
||||||
Error **errp);
|
Error **errp);
|
||||||
|
|
||||||
/* May be NULL */
|
/* May be NULL; most useful for input visitors. */
|
||||||
void (*optional)(Visitor *v, bool *present, const char *name,
|
void (*optional)(Visitor *v, bool *present, const char *name);
|
||||||
Error **errp);
|
|
||||||
|
|
||||||
void (*type_uint8)(Visitor *v, uint8_t *obj, const char *name, Error **errp);
|
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);
|
void (*type_uint16)(Visitor *v, uint16_t *obj, const char *name, Error **errp);
|
||||||
|
@ -27,9 +27,6 @@ typedef struct GenericList
|
|||||||
struct GenericList *next;
|
struct GenericList *next;
|
||||||
} GenericList;
|
} 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,
|
void visit_start_struct(Visitor *v, void **obj, const char *kind,
|
||||||
const char *name, size_t size, Error **errp);
|
const char *name, size_t size, Error **errp);
|
||||||
void visit_end_struct(Visitor *v, Error **errp);
|
void visit_end_struct(Visitor *v, Error **errp);
|
||||||
@ -39,9 +36,22 @@ void visit_end_implicit_struct(Visitor *v, Error **errp);
|
|||||||
void visit_start_list(Visitor *v, const char *name, Error **errp);
|
void visit_start_list(Visitor *v, const char *name, Error **errp);
|
||||||
GenericList *visit_next_list(Visitor *v, GenericList **list, Error **errp);
|
GenericList *visit_next_list(Visitor *v, GenericList **list, Error **errp);
|
||||||
void visit_end_list(Visitor *v, 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,
|
* 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. Return *@present for convenience.
|
||||||
|
*/
|
||||||
|
bool 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, bool promote_int,
|
||||||
const char *name, Error **errp);
|
const char *name, Error **errp);
|
||||||
void visit_type_enum(Visitor *v, int *obj, const char * const strings[],
|
void visit_type_enum(Visitor *v, int *obj, const char * const strings[],
|
||||||
const char *kind, const char *name, Error **errp);
|
const char *kind, const char *name, Error **errp);
|
||||||
|
@ -80,6 +80,7 @@ typedef struct QEMUSGList QEMUSGList;
|
|||||||
typedef struct QEMUSizedBuffer QEMUSizedBuffer;
|
typedef struct QEMUSizedBuffer QEMUSizedBuffer;
|
||||||
typedef struct QEMUTimer QEMUTimer;
|
typedef struct QEMUTimer QEMUTimer;
|
||||||
typedef struct QEMUTimerListGroup QEMUTimerListGroup;
|
typedef struct QEMUTimerListGroup QEMUTimerListGroup;
|
||||||
|
typedef struct QObject QObject;
|
||||||
typedef struct RAMBlock RAMBlock;
|
typedef struct RAMBlock RAMBlock;
|
||||||
typedef struct Range Range;
|
typedef struct Range Range;
|
||||||
typedef struct SerialState SerialState;
|
typedef struct SerialState SerialState;
|
||||||
|
@ -202,7 +202,7 @@ static int global_state_post_load(void *opaque, int version_id)
|
|||||||
s->received = true;
|
s->received = true;
|
||||||
trace_migrate_global_state_post_load(runstate);
|
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);
|
-1, &local_err);
|
||||||
|
|
||||||
if (r == -1) {
|
if (r == -1) {
|
||||||
@ -479,7 +479,7 @@ MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
caps = NULL; /* silence compiler warning */
|
caps = NULL; /* silence compiler warning */
|
||||||
for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) {
|
for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) {
|
||||||
if (head == NULL) {
|
if (head == NULL) {
|
||||||
head = g_malloc0(sizeof(*caps));
|
head = g_malloc0(sizeof(*caps));
|
||||||
caps = head;
|
caps = head;
|
||||||
|
18
monitor.c
18
monitor.c
@ -403,7 +403,7 @@ static QDict *build_qmp_error_dict(Error *err)
|
|||||||
QObject *obj;
|
QObject *obj;
|
||||||
|
|
||||||
obj = qobject_from_jsonf("{ 'error': { 'class': %s, 'desc': %s } }",
|
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));
|
error_get_pretty(err));
|
||||||
|
|
||||||
return qobject_to_qdict(obj);
|
return qobject_to_qdict(obj);
|
||||||
@ -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 */
|
/* Limit guest-triggerable events to 1 per second */
|
||||||
[QAPI_EVENT_RTC_CHANGE] = { 1000 * SCALE_MS },
|
[QAPI_EVENT_RTC_CHANGE] = { 1000 * SCALE_MS },
|
||||||
[QAPI_EVENT_WATCHDOG] = { 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;
|
MonitorQAPIEventConf *evconf;
|
||||||
MonitorQAPIEventState *evstate;
|
MonitorQAPIEventState *evstate;
|
||||||
|
|
||||||
assert(event < QAPI_EVENT_MAX);
|
assert(event < QAPI_EVENT__MAX);
|
||||||
evconf = &monitor_qapi_event_conf[event];
|
evconf = &monitor_qapi_event_conf[event];
|
||||||
trace_monitor_protocol_event_queue(event, qdict, evconf->rate);
|
trace_monitor_protocol_event_queue(event, qdict, evconf->rate);
|
||||||
|
|
||||||
@ -946,7 +946,7 @@ EventInfoList *qmp_query_events(Error **errp)
|
|||||||
EventInfoList *info, *ev_list = NULL;
|
EventInfoList *info, *ev_list = NULL;
|
||||||
QAPIEvent e;
|
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];
|
const char *event_name = QAPIEvent_lookup[e];
|
||||||
assert(event_name != NULL);
|
assert(event_name != NULL);
|
||||||
info = g_malloc0(sizeof(*info));
|
info = g_malloc0(sizeof(*info));
|
||||||
@ -1375,7 +1375,7 @@ static void hmp_mouse_move(Monitor *mon, const QDict *qdict)
|
|||||||
if (dz_str) {
|
if (dz_str) {
|
||||||
dz = strtol(dz_str, NULL, 0);
|
dz = strtol(dz_str, NULL, 0);
|
||||||
if (dz != 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_queue_btn(NULL, button, true);
|
||||||
qemu_input_event_sync();
|
qemu_input_event_sync();
|
||||||
qemu_input_queue_btn(NULL, button, false);
|
qemu_input_queue_btn(NULL, button, false);
|
||||||
@ -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 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_LEFT] = MOUSE_EVENT_LBUTTON,
|
||||||
[INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON,
|
[INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON,
|
||||||
[INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON,
|
[INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON,
|
||||||
@ -3217,7 +3217,7 @@ void sendkey_completion(ReadLineState *rs, int nb_args, const char *str)
|
|||||||
}
|
}
|
||||||
len = strlen(str);
|
len = strlen(str);
|
||||||
readline_set_completion_index(rs, len);
|
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)) {
|
if (!strncmp(str, QKeyCode_lookup[i], len)) {
|
||||||
readline_add_completion(rs, QKeyCode_lookup[i]);
|
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);
|
readline_set_completion_index(rs, len);
|
||||||
if (nb_args == 2) {
|
if (nb_args == 2) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) {
|
for (i = 0; i < MIGRATION_CAPABILITY__MAX; i++) {
|
||||||
const char *name = MigrationCapability_lookup[i];
|
const char *name = MigrationCapability_lookup[i];
|
||||||
if (!strncmp(str, name, len)) {
|
if (!strncmp(str, name, len)) {
|
||||||
readline_add_completion(rs, name);
|
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);
|
readline_set_completion_index(rs, len);
|
||||||
if (nb_args == 2) {
|
if (nb_args == 2) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < MIGRATION_PARAMETER_MAX; i++) {
|
for (i = 0; i < MIGRATION_PARAMETER__MAX; i++) {
|
||||||
const char *name = MigrationParameter_lookup[i];
|
const char *name = MigrationParameter_lookup[i];
|
||||||
if (!strncmp(str, name, len)) {
|
if (!strncmp(str, name, len)) {
|
||||||
readline_add_completion(rs, name);
|
readline_add_completion(rs, name);
|
||||||
|
@ -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 NetClientOptions *opts,
|
||||||
const char *name,
|
const char *name,
|
||||||
NetClientState *peer, Error **errp) = {
|
NetClientState *peer, Error **errp) = {
|
||||||
@ -1296,7 +1296,7 @@ void qmp_set_link(const char *name, bool up, Error **errp)
|
|||||||
int queues, i;
|
int queues, i;
|
||||||
|
|
||||||
queues = qemu_find_net_clients_except(name, ncs,
|
queues = qemu_find_net_clients_except(name, ncs,
|
||||||
NET_CLIENT_OPTIONS_KIND_MAX,
|
NET_CLIENT_OPTIONS_KIND__MAX,
|
||||||
MAX_QUEUE_NUM);
|
MAX_QUEUE_NUM);
|
||||||
|
|
||||||
if (queues == 0) {
|
if (queues == 0) {
|
||||||
|
120
qapi-schema.json
120
qapi-schema.json
@ -744,43 +744,125 @@
|
|||||||
{ 'command': 'query-mice', 'returns': ['MouseInfo'] }
|
{ 'command': 'query-mice', 'returns': ['MouseInfo'] }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @CpuInfo:
|
# @CpuInfoArch:
|
||||||
#
|
#
|
||||||
# Information about a virtual CPU
|
# An enumeration of cpu types that enable additional information during
|
||||||
|
# @query-cpus.
|
||||||
|
#
|
||||||
|
# Since: 2.6
|
||||||
|
##
|
||||||
|
{ 'enum': 'CpuInfoArch',
|
||||||
|
'data': ['x86', 'sparc', 'ppc', 'mips', 'tricore', 'other' ] }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @CpuInfoBase:
|
||||||
|
#
|
||||||
|
# Common information about a virtual CPU
|
||||||
#
|
#
|
||||||
# @CPU: the index of the virtual CPU
|
# @CPU: the index of the virtual CPU
|
||||||
#
|
#
|
||||||
# @current: this only exists for backwards compatible and should be ignored
|
# @current: this only exists for backwards compatibility and should be ignored
|
||||||
#
|
#
|
||||||
# @halted: true if the virtual CPU is in the halt state. Halt usually refers
|
# @halted: true if the virtual CPU is in the halt state. Halt usually refers
|
||||||
# to a processor specific low power mode.
|
# to a processor specific low power mode.
|
||||||
#
|
#
|
||||||
# @qom_path: path to the CPU object in the QOM tree (since 2.4)
|
# @qom_path: path to the CPU object in the QOM tree (since 2.4)
|
||||||
#
|
#
|
||||||
# @pc: #optional If the target is i386 or x86_64, this is the 64-bit instruction
|
|
||||||
# pointer.
|
|
||||||
# If the target is Sparc, this is the PC component of the
|
|
||||||
# instruction pointer.
|
|
||||||
#
|
|
||||||
# @nip: #optional If the target is PPC, the instruction pointer
|
|
||||||
#
|
|
||||||
# @npc: #optional If the target is Sparc, the NPC component of the instruction
|
|
||||||
# pointer
|
|
||||||
#
|
|
||||||
# @PC: #optional If the target is MIPS, the instruction pointer
|
|
||||||
#
|
|
||||||
# @thread_id: ID of the underlying host thread
|
# @thread_id: ID of the underlying host thread
|
||||||
#
|
#
|
||||||
|
# @arch: architecture of the cpu, which determines which additional fields
|
||||||
|
# will be listed (since 2.6)
|
||||||
|
#
|
||||||
# Since: 0.14.0
|
# Since: 0.14.0
|
||||||
#
|
#
|
||||||
# Notes: @halted is a transient state that changes frequently. By the time the
|
# Notes: @halted is a transient state that changes frequently. By the time the
|
||||||
# data is sent to the client, the guest may no longer be halted.
|
# data is sent to the client, the guest may no longer be halted.
|
||||||
##
|
##
|
||||||
{ 'struct': 'CpuInfo',
|
{ 'struct': 'CpuInfoBase',
|
||||||
'data': {'CPU': 'int', 'current': 'bool', 'halted': 'bool',
|
'data': {'CPU': 'int', 'current': 'bool', 'halted': 'bool',
|
||||||
'qom_path': 'str',
|
'qom_path': 'str', 'thread_id': 'int', 'arch': 'CpuInfoArch' } }
|
||||||
'*pc': 'int', '*nip': 'int', '*npc': 'int', '*PC': 'int',
|
|
||||||
'thread_id': 'int'} }
|
##
|
||||||
|
# @CpuInfo:
|
||||||
|
#
|
||||||
|
# Information about a virtual CPU
|
||||||
|
#
|
||||||
|
# Since: 0.14.0
|
||||||
|
##
|
||||||
|
{ 'union': 'CpuInfo', 'base': 'CpuInfoBase', 'discriminator': 'arch',
|
||||||
|
'data': { 'x86': 'CpuInfoX86',
|
||||||
|
'sparc': 'CpuInfoSPARC',
|
||||||
|
'ppc': 'CpuInfoPPC',
|
||||||
|
'mips': 'CpuInfoMIPS',
|
||||||
|
'tricore': 'CpuInfoTricore',
|
||||||
|
'other': 'CpuInfoOther' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @CpuInfoX86:
|
||||||
|
#
|
||||||
|
# Additional information about a virtual i386 or x86_64 CPU
|
||||||
|
#
|
||||||
|
# @pc: the 64-bit instruction pointer
|
||||||
|
#
|
||||||
|
# Since 2.6
|
||||||
|
##
|
||||||
|
{ 'struct': 'CpuInfoX86', 'data': { 'pc': 'int' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @CpuInfoSPARC:
|
||||||
|
#
|
||||||
|
# Additional information about a virtual SPARC CPU
|
||||||
|
#
|
||||||
|
# @pc: the PC component of the instruction pointer
|
||||||
|
#
|
||||||
|
# @npc: the NPC component of the instruction pointer
|
||||||
|
#
|
||||||
|
# Since 2.6
|
||||||
|
##
|
||||||
|
{ 'struct': 'CpuInfoSPARC', 'data': { 'pc': 'int', 'npc': 'int' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @CpuInfoPPC:
|
||||||
|
#
|
||||||
|
# Additional information about a virtual PPC CPU
|
||||||
|
#
|
||||||
|
# @nip: the instruction pointer
|
||||||
|
#
|
||||||
|
# Since 2.6
|
||||||
|
##
|
||||||
|
{ 'struct': 'CpuInfoPPC', 'data': { 'nip': 'int' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @CpuInfoMIPS:
|
||||||
|
#
|
||||||
|
# Additional information about a virtual MIPS CPU
|
||||||
|
#
|
||||||
|
# @PC: the instruction pointer
|
||||||
|
#
|
||||||
|
# Since 2.6
|
||||||
|
##
|
||||||
|
{ 'struct': 'CpuInfoMIPS', 'data': { 'PC': 'int' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @CpuInfoTricore:
|
||||||
|
#
|
||||||
|
# Additional information about a virtual Tricore CPU
|
||||||
|
#
|
||||||
|
# @PC: the instruction pointer
|
||||||
|
#
|
||||||
|
# Since 2.6
|
||||||
|
##
|
||||||
|
{ 'struct': 'CpuInfoTricore', 'data': { 'PC': 'int' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @CpuInfoOther:
|
||||||
|
#
|
||||||
|
# No additional information is available about the virtual CPU
|
||||||
|
#
|
||||||
|
# Since 2.6
|
||||||
|
#
|
||||||
|
##
|
||||||
|
{ 'struct': 'CpuInfoOther', 'data': { } }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @query-cpus:
|
# @query-cpus:
|
||||||
|
@ -1776,21 +1776,23 @@
|
|||||||
# @BlkdebugEvent
|
# @BlkdebugEvent
|
||||||
#
|
#
|
||||||
# Trigger events supported by blkdebug.
|
# 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',
|
'data': [ 'l1_update', 'l1_grow_alloc_table', 'l1_grow_write_table',
|
||||||
'l1_grow.activate_table', 'l2_load', 'l2_update',
|
'l1_grow_activate_table', 'l2_load', 'l2_update',
|
||||||
'l2_update_compressed', 'l2_alloc.cow_read', 'l2_alloc.write',
|
'l2_update_compressed', 'l2_alloc_cow_read', 'l2_alloc_write',
|
||||||
'read_aio', 'read_backing_aio', 'read_compressed', 'write_aio',
|
'read_aio', 'read_backing_aio', 'read_compressed', 'write_aio',
|
||||||
'write_compressed', 'vmstate_load', 'vmstate_save', 'cow_read',
|
'write_compressed', 'vmstate_load', 'vmstate_save', 'cow_read',
|
||||||
'cow_write', 'reftable_load', 'reftable_grow', 'reftable_update',
|
'cow_write', 'reftable_load', 'reftable_grow', 'reftable_update',
|
||||||
'refblock_load', 'refblock_update', 'refblock_update_part',
|
'refblock_load', 'refblock_update', 'refblock_update_part',
|
||||||
'refblock_alloc', 'refblock_alloc.hookup', 'refblock_alloc.write',
|
'refblock_alloc', 'refblock_alloc_hookup', 'refblock_alloc_write',
|
||||||
'refblock_alloc.write_blocks', 'refblock_alloc.write_table',
|
'refblock_alloc_write_blocks', 'refblock_alloc_write_table',
|
||||||
'refblock_alloc.switch_table', 'cluster_alloc',
|
'refblock_alloc_switch_table', 'cluster_alloc',
|
||||||
'cluster_alloc_bytes', 'cluster_free', 'flush_to_os',
|
'cluster_alloc_bytes', 'cluster_free', 'flush_to_os',
|
||||||
'flush_to_disk', 'pwritev_rmw.head', 'pwritev_rmw.after_head',
|
'flush_to_disk', 'pwritev_rmw_head', 'pwritev_rmw_after_head',
|
||||||
'pwritev_rmw.tail', 'pwritev_rmw.after_tail', 'pwritev',
|
'pwritev_rmw_tail', 'pwritev_rmw_after_tail', 'pwritev',
|
||||||
'pwritev_zero', 'pwritev_done', 'empty_image_prepare' ] }
|
'pwritev_zero', 'pwritev_done', 'empty_image_prepare' ] }
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
# QAPI common definitions
|
# QAPI common definitions
|
||||||
|
|
||||||
##
|
##
|
||||||
# @ErrorClass
|
# @QapiErrorClass
|
||||||
#
|
#
|
||||||
# QEMU error classes
|
# QEMU error classes
|
||||||
#
|
#
|
||||||
@ -24,7 +24,8 @@
|
|||||||
#
|
#
|
||||||
# Since: 1.2
|
# Since: 1.2
|
||||||
##
|
##
|
||||||
{ 'enum': 'ErrorClass',
|
{ 'enum': 'QapiErrorClass',
|
||||||
|
# Keep this in sync with ErrorClass in error.h
|
||||||
'data': [ 'GenericError', 'CommandNotFound', 'DeviceEncrypted',
|
'data': [ 'GenericError', 'CommandNotFound', 'DeviceEncrypted',
|
||||||
'DeviceNotActive', 'DeviceNotFound', 'KVMMissingCap' ] }
|
'DeviceNotActive', 'DeviceNotFound', 'KVMMissingCap' ] }
|
||||||
|
|
||||||
|
@ -488,7 +488,7 @@ opts_type_size(Visitor *v, uint64_t *obj, const char *name, Error **errp)
|
|||||||
|
|
||||||
|
|
||||||
static void
|
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);
|
OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v);
|
||||||
|
|
||||||
|
@ -73,19 +73,19 @@ 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)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
if (v->optional) {
|
if (v->optional) {
|
||||||
v->optional(v, present, name, errp);
|
v->optional(v, present, name);
|
||||||
}
|
}
|
||||||
|
return *present;
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit_get_next_type(Visitor *v, int *obj, const int *qtypes,
|
void visit_get_next_type(Visitor *v, QType *type, bool promote_int,
|
||||||
const char *name, Error **errp)
|
const char *name, Error **errp)
|
||||||
{
|
{
|
||||||
if (v->get_next_type) {
|
if (v->get_next_type) {
|
||||||
v->get_next_type(v, obj, qtypes, name, errp);
|
v->get_next_type(v, type, promote_int, name, errp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ static QObject *do_qmp_dispatch(QObject *request, Error **errp)
|
|||||||
QObject *qmp_build_error_object(Error *err)
|
QObject *qmp_build_error_object(Error *err)
|
||||||
{
|
{
|
||||||
return qobject_from_jsonf("{ 'class': %s, 'desc': %s }",
|
return qobject_from_jsonf("{ 'class': %s, 'desc': %s }",
|
||||||
ErrorClass_lookup[error_get_class(err)],
|
QapiErrorClass_lookup[error_get_class(err)],
|
||||||
error_get_pretty(err));
|
error_get_pretty(err));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,7 +208,7 @@ static void qmp_input_end_list(Visitor *v, Error **errp)
|
|||||||
qmp_input_pop(qiv, 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, bool promote_int,
|
||||||
const char *name, Error **errp)
|
const char *name, Error **errp)
|
||||||
{
|
{
|
||||||
QmpInputVisitor *qiv = to_qiv(v);
|
QmpInputVisitor *qiv = to_qiv(v);
|
||||||
@ -218,7 +218,10 @@ static void qmp_input_get_next_type(Visitor *v, int *kind, const int *qobjects,
|
|||||||
error_setg(errp, QERR_MISSING_PARAMETER, name ? name : "null");
|
error_setg(errp, QERR_MISSING_PARAMETER, name ? name : "null");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*kind = qobjects[qobject_type(qobj)];
|
*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,
|
static void qmp_input_type_int(Visitor *v, int64_t *obj, const char *name,
|
||||||
@ -300,8 +303,7 @@ static void qmp_input_type_any(Visitor *v, QObject **obj, const char *name,
|
|||||||
*obj = qobj;
|
*obj = qobj;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qmp_input_optional(Visitor *v, bool *present, const char *name,
|
static void qmp_input_optional(Visitor *v, bool *present, const char *name)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
QmpInputVisitor *qiv = to_qiv(v);
|
QmpInputVisitor *qiv = to_qiv(v);
|
||||||
QObject *qobj = qmp_input_get_object(qiv, name, true);
|
QObject *qobj = qmp_input_get_object(qiv, name, true);
|
||||||
|
@ -299,8 +299,7 @@ static void parse_type_number(Visitor *v, double *obj, const char *name,
|
|||||||
*obj = val;
|
*obj = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void parse_optional(Visitor *v, bool *present, const char *name,
|
static void parse_optional(Visitor *v, bool *present, const char *name)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
|
StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
|
||||||
|
|
||||||
|
@ -487,7 +487,7 @@ int main(int argc, char **argv)
|
|||||||
detect_zeroes =
|
detect_zeroes =
|
||||||
qapi_enum_parse(BlockdevDetectZeroesOptions_lookup,
|
qapi_enum_parse(BlockdevDetectZeroesOptions_lookup,
|
||||||
optarg,
|
optarg,
|
||||||
BLOCKDEV_DETECT_ZEROES_OPTIONS_MAX,
|
BLOCKDEV_DETECT_ZEROES_OPTIONS__MAX,
|
||||||
BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF,
|
BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF,
|
||||||
&local_err);
|
&local_err);
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
|
@ -2765,6 +2765,8 @@ Return a json-array. Each CPU is represented by a json-object, which contains:
|
|||||||
- "current": true if this is the current CPU, false otherwise (json-bool)
|
- "current": true if this is the current CPU, false otherwise (json-bool)
|
||||||
- "halted": true if the cpu is halted, false otherwise (json-bool)
|
- "halted": true if the cpu is halted, false otherwise (json-bool)
|
||||||
- "qom_path": path to the CPU object in the QOM tree (json-str)
|
- "qom_path": path to the CPU object in the QOM tree (json-str)
|
||||||
|
- "arch": architecture of the cpu, which determines what additional
|
||||||
|
keys will be present (json-str)
|
||||||
- Current program counter. The key's name depends on the architecture:
|
- Current program counter. The key's name depends on the architecture:
|
||||||
"pc": i386/x86_64 (json-int)
|
"pc": i386/x86_64 (json-int)
|
||||||
"nip": PPC (json-int)
|
"nip": PPC (json-int)
|
||||||
@ -2782,6 +2784,7 @@ Example:
|
|||||||
"current":true,
|
"current":true,
|
||||||
"halted":false,
|
"halted":false,
|
||||||
"qom_path":"/machine/unattached/device[0]",
|
"qom_path":"/machine/unattached/device[0]",
|
||||||
|
"arch":"x86",
|
||||||
"pc":3227107138,
|
"pc":3227107138,
|
||||||
"thread_id":3134
|
"thread_id":3134
|
||||||
},
|
},
|
||||||
@ -2790,6 +2793,7 @@ Example:
|
|||||||
"current":false,
|
"current":false,
|
||||||
"halted":true,
|
"halted":true,
|
||||||
"qom_path":"/machine/unattached/device[2]",
|
"qom_path":"/machine/unattached/device[2]",
|
||||||
|
"arch":"x86",
|
||||||
"pc":7108165,
|
"pc":7108165,
|
||||||
"thread_id":3135
|
"thread_id":3135
|
||||||
}
|
}
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
util-obj-y = qnull.o qint.o qstring.o qdict.o qlist.o qfloat.o qbool.o
|
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
|
||||||
|
@ -15,13 +15,6 @@
|
|||||||
#include "qapi/qmp/qobject.h"
|
#include "qapi/qmp/qobject.h"
|
||||||
#include "qemu-common.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
|
* qbool_from_bool(): Create a new QBool from a bool
|
||||||
*
|
*
|
||||||
@ -32,8 +25,8 @@ QBool *qbool_from_bool(bool value)
|
|||||||
QBool *qb;
|
QBool *qb;
|
||||||
|
|
||||||
qb = g_malloc(sizeof(*qb));
|
qb = g_malloc(sizeof(*qb));
|
||||||
|
qobject_init(QOBJECT(qb), QTYPE_QBOOL);
|
||||||
qb->value = value;
|
qb->value = value;
|
||||||
QOBJECT_INIT(qb, &qbool_type);
|
|
||||||
|
|
||||||
return qb;
|
return qb;
|
||||||
}
|
}
|
||||||
@ -61,7 +54,7 @@ QBool *qobject_to_qbool(const QObject *obj)
|
|||||||
* qbool_destroy_obj(): Free all memory allocated by a
|
* qbool_destroy_obj(): Free all memory allocated by a
|
||||||
* QBool object
|
* QBool object
|
||||||
*/
|
*/
|
||||||
static void qbool_destroy_obj(QObject *obj)
|
void qbool_destroy_obj(QObject *obj)
|
||||||
{
|
{
|
||||||
assert(obj != NULL);
|
assert(obj != NULL);
|
||||||
g_free(qobject_to_qbool(obj));
|
g_free(qobject_to_qbool(obj));
|
||||||
|
@ -19,13 +19,6 @@
|
|||||||
#include "qemu/queue.h"
|
#include "qemu/queue.h"
|
||||||
#include "qemu-common.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
|
* qdict_new(): Create a new QDict
|
||||||
*
|
*
|
||||||
@ -36,7 +29,7 @@ QDict *qdict_new(void)
|
|||||||
QDict *qdict;
|
QDict *qdict;
|
||||||
|
|
||||||
qdict = g_malloc0(sizeof(*qdict));
|
qdict = g_malloc0(sizeof(*qdict));
|
||||||
QOBJECT_INIT(qdict, &qdict_type);
|
qobject_init(QOBJECT(qdict), QTYPE_QDICT);
|
||||||
|
|
||||||
return qdict;
|
return qdict;
|
||||||
}
|
}
|
||||||
@ -184,8 +177,7 @@ size_t qdict_size(const QDict *qdict)
|
|||||||
/**
|
/**
|
||||||
* qdict_get_obj(): Get a QObject of a specific type
|
* qdict_get_obj(): Get a QObject of a specific type
|
||||||
*/
|
*/
|
||||||
static QObject *qdict_get_obj(const QDict *qdict, const char *key,
|
static QObject *qdict_get_obj(const QDict *qdict, const char *key, QType type)
|
||||||
qtype_code type)
|
|
||||||
{
|
{
|
||||||
QObject *obj;
|
QObject *obj;
|
||||||
|
|
||||||
@ -441,7 +433,7 @@ void qdict_del(QDict *qdict, const char *key)
|
|||||||
/**
|
/**
|
||||||
* qdict_destroy_obj(): Free all the memory allocated by a QDict
|
* 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;
|
int i;
|
||||||
QDict *qdict;
|
QDict *qdict;
|
||||||
|
@ -15,13 +15,6 @@
|
|||||||
#include "qapi/qmp/qobject.h"
|
#include "qapi/qmp/qobject.h"
|
||||||
#include "qemu-common.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
|
* qfloat_from_int(): Create a new QFloat from a float
|
||||||
*
|
*
|
||||||
@ -32,8 +25,8 @@ QFloat *qfloat_from_double(double value)
|
|||||||
QFloat *qf;
|
QFloat *qf;
|
||||||
|
|
||||||
qf = g_malloc(sizeof(*qf));
|
qf = g_malloc(sizeof(*qf));
|
||||||
|
qobject_init(QOBJECT(qf), QTYPE_QFLOAT);
|
||||||
qf->value = value;
|
qf->value = value;
|
||||||
QOBJECT_INIT(qf, &qfloat_type);
|
|
||||||
|
|
||||||
return qf;
|
return qf;
|
||||||
}
|
}
|
||||||
@ -61,7 +54,7 @@ QFloat *qobject_to_qfloat(const QObject *obj)
|
|||||||
* qfloat_destroy_obj(): Free all memory allocated by a
|
* qfloat_destroy_obj(): Free all memory allocated by a
|
||||||
* QFloat object
|
* QFloat object
|
||||||
*/
|
*/
|
||||||
static void qfloat_destroy_obj(QObject *obj)
|
void qfloat_destroy_obj(QObject *obj)
|
||||||
{
|
{
|
||||||
assert(obj != NULL);
|
assert(obj != NULL);
|
||||||
g_free(qobject_to_qfloat(obj));
|
g_free(qobject_to_qfloat(obj));
|
||||||
|
@ -14,13 +14,6 @@
|
|||||||
#include "qapi/qmp/qobject.h"
|
#include "qapi/qmp/qobject.h"
|
||||||
#include "qemu-common.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
|
* qint_from_int(): Create a new QInt from an int64_t
|
||||||
*
|
*
|
||||||
@ -31,8 +24,8 @@ QInt *qint_from_int(int64_t value)
|
|||||||
QInt *qi;
|
QInt *qi;
|
||||||
|
|
||||||
qi = g_malloc(sizeof(*qi));
|
qi = g_malloc(sizeof(*qi));
|
||||||
|
qobject_init(QOBJECT(qi), QTYPE_QINT);
|
||||||
qi->value = value;
|
qi->value = value;
|
||||||
QOBJECT_INIT(qi, &qint_type);
|
|
||||||
|
|
||||||
return qi;
|
return qi;
|
||||||
}
|
}
|
||||||
@ -60,7 +53,7 @@ QInt *qobject_to_qint(const QObject *obj)
|
|||||||
* qint_destroy_obj(): Free all memory allocated by a
|
* qint_destroy_obj(): Free all memory allocated by a
|
||||||
* QInt object
|
* QInt object
|
||||||
*/
|
*/
|
||||||
static void qint_destroy_obj(QObject *obj)
|
void qint_destroy_obj(QObject *obj)
|
||||||
{
|
{
|
||||||
assert(obj != NULL);
|
assert(obj != NULL);
|
||||||
g_free(qobject_to_qint(obj));
|
g_free(qobject_to_qint(obj));
|
||||||
|
@ -15,13 +15,6 @@
|
|||||||
#include "qemu/queue.h"
|
#include "qemu/queue.h"
|
||||||
#include "qemu-common.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
|
* qlist_new(): Create a new QList
|
||||||
*
|
*
|
||||||
@ -32,8 +25,8 @@ QList *qlist_new(void)
|
|||||||
QList *qlist;
|
QList *qlist;
|
||||||
|
|
||||||
qlist = g_malloc(sizeof(*qlist));
|
qlist = g_malloc(sizeof(*qlist));
|
||||||
|
qobject_init(QOBJECT(qlist), QTYPE_QLIST);
|
||||||
QTAILQ_INIT(&qlist->head);
|
QTAILQ_INIT(&qlist->head);
|
||||||
QOBJECT_INIT(qlist, &qlist_type);
|
|
||||||
|
|
||||||
return qlist;
|
return qlist;
|
||||||
}
|
}
|
||||||
@ -151,7 +144,7 @@ QList *qobject_to_qlist(const QObject *obj)
|
|||||||
/**
|
/**
|
||||||
* qlist_destroy_obj(): Free all the memory allocated by a QList
|
* 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;
|
QList *qlist;
|
||||||
QListEntry *entry, *next_entry;
|
QListEntry *entry, *next_entry;
|
||||||
|
@ -13,17 +13,7 @@
|
|||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
#include "qapi/qmp/qobject.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_ = {
|
QObject qnull_ = {
|
||||||
.type = &qnull_type,
|
.type = QTYPE_QNULL,
|
||||||
.refcnt = 1,
|
.refcnt = 1,
|
||||||
};
|
};
|
||||||
|
34
qobject/qobject.c
Normal file
34
qobject/qobject.c
Normal file
@ -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);
|
||||||
|
}
|
@ -14,13 +14,6 @@
|
|||||||
#include "qapi/qmp/qstring.h"
|
#include "qapi/qmp/qstring.h"
|
||||||
#include "qemu-common.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
|
* 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 *qstring;
|
||||||
|
|
||||||
qstring = g_malloc(sizeof(*qstring));
|
qstring = g_malloc(sizeof(*qstring));
|
||||||
|
qobject_init(QOBJECT(qstring), QTYPE_QSTRING);
|
||||||
|
|
||||||
qstring->length = end - start + 1;
|
qstring->length = end - start + 1;
|
||||||
qstring->capacity = qstring->length;
|
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);
|
memcpy(qstring->string, str + start, qstring->length);
|
||||||
qstring->string[qstring->length] = 0;
|
qstring->string[qstring->length] = 0;
|
||||||
|
|
||||||
QOBJECT_INIT(qstring, &qstring_type);
|
|
||||||
|
|
||||||
return qstring;
|
return qstring;
|
||||||
}
|
}
|
||||||
@ -138,7 +131,7 @@ const char *qstring_get_str(const QString *qstring)
|
|||||||
* qstring_destroy_obj(): Free all memory allocated by a QString
|
* qstring_destroy_obj(): Free all memory allocated by a QString
|
||||||
* object
|
* object
|
||||||
*/
|
*/
|
||||||
static void qstring_destroy_obj(QObject *obj)
|
void qstring_destroy_obj(QObject *obj)
|
||||||
{
|
{
|
||||||
QString *qs;
|
QString *qs;
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ void replay_save_input_event(InputEvent *evt)
|
|||||||
replay_put_dword(evt->u.key->key->u.qcode);
|
replay_put_dword(evt->u.key->key->u.qcode);
|
||||||
replay_put_byte(evt->u.key->down);
|
replay_put_byte(evt->u.key->down);
|
||||||
break;
|
break;
|
||||||
case KEY_VALUE_KIND_MAX:
|
case KEY_VALUE_KIND__MAX:
|
||||||
/* keep gcc happy */
|
/* keep gcc happy */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -78,7 +78,7 @@ void replay_save_input_event(InputEvent *evt)
|
|||||||
replay_put_dword(evt->u.abs->axis);
|
replay_put_dword(evt->u.abs->axis);
|
||||||
replay_put_qword(evt->u.abs->value);
|
replay_put_qword(evt->u.abs->value);
|
||||||
break;
|
break;
|
||||||
case INPUT_EVENT_KIND_MAX:
|
case INPUT_EVENT_KIND__MAX:
|
||||||
/* keep gcc happy */
|
/* keep gcc happy */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -109,7 +109,7 @@ InputEvent *replay_read_input_event(void)
|
|||||||
evt.u.key->key->u.qcode = (QKeyCode)replay_get_dword();
|
evt.u.key->key->u.qcode = (QKeyCode)replay_get_dword();
|
||||||
evt.u.key->down = replay_get_byte();
|
evt.u.key->down = replay_get_byte();
|
||||||
break;
|
break;
|
||||||
case KEY_VALUE_KIND_MAX:
|
case KEY_VALUE_KIND__MAX:
|
||||||
/* keep gcc happy */
|
/* keep gcc happy */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -129,7 +129,7 @@ InputEvent *replay_read_input_event(void)
|
|||||||
evt.u.abs->axis = (InputAxis)replay_get_dword();
|
evt.u.abs->axis = (InputAxis)replay_get_dword();
|
||||||
evt.u.abs->value = replay_get_qword();
|
evt.u.abs->value = replay_get_qword();
|
||||||
break;
|
break;
|
||||||
case INPUT_EVENT_KIND_MAX:
|
case INPUT_EVENT_KIND__MAX:
|
||||||
/* keep gcc happy */
|
/* keep gcc happy */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -36,54 +36,47 @@ struct %(c_name)s {
|
|||||||
c_name=c_name(name), c_type=element_type.c_type())
|
c_name=c_name(name), c_type=element_type.c_type())
|
||||||
|
|
||||||
|
|
||||||
def gen_struct_field(member):
|
def gen_struct_fields(members):
|
||||||
ret = ''
|
ret = ''
|
||||||
|
for memb in members:
|
||||||
if member.optional:
|
if memb.optional:
|
||||||
ret += mcgen('''
|
ret += mcgen('''
|
||||||
bool has_%(c_name)s;
|
bool has_%(c_name)s;
|
||||||
''',
|
''',
|
||||||
c_name=c_name(member.name))
|
c_name=c_name(memb.name))
|
||||||
ret += mcgen('''
|
ret += mcgen('''
|
||||||
%(c_type)s %(c_name)s;
|
%(c_type)s %(c_name)s;
|
||||||
''',
|
''',
|
||||||
c_type=member.type.c_type(), c_name=c_name(member.name))
|
c_type=memb.type.c_type(), c_name=c_name(memb.name))
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def gen_struct_fields(local_members, base=None):
|
def gen_object(name, base, members, variants):
|
||||||
ret = ''
|
|
||||||
|
|
||||||
if base:
|
|
||||||
ret += mcgen('''
|
|
||||||
/* Members inherited from %(c_name)s: */
|
|
||||||
''',
|
|
||||||
c_name=base.c_name())
|
|
||||||
for memb in base.members:
|
|
||||||
ret += gen_struct_field(memb)
|
|
||||||
ret += mcgen('''
|
|
||||||
/* Own members: */
|
|
||||||
''')
|
|
||||||
|
|
||||||
for memb in local_members:
|
|
||||||
ret += gen_struct_field(memb)
|
|
||||||
return ret
|
|
||||||
|
|
||||||
|
|
||||||
def gen_struct(name, base, members):
|
|
||||||
ret = mcgen('''
|
ret = mcgen('''
|
||||||
|
|
||||||
struct %(c_name)s {
|
struct %(c_name)s {
|
||||||
''',
|
''',
|
||||||
c_name=c_name(name))
|
c_name=c_name(name))
|
||||||
|
|
||||||
ret += gen_struct_fields(members, base)
|
if base:
|
||||||
|
ret += mcgen('''
|
||||||
|
/* Members inherited from %(c_name)s: */
|
||||||
|
''',
|
||||||
|
c_name=base.c_name())
|
||||||
|
ret += gen_struct_fields(base.members)
|
||||||
|
ret += mcgen('''
|
||||||
|
/* Own members: */
|
||||||
|
''')
|
||||||
|
ret += gen_struct_fields(members)
|
||||||
|
|
||||||
|
if variants:
|
||||||
|
ret += gen_variants(variants)
|
||||||
|
|
||||||
# Make sure that all structs have at least one field; this avoids
|
# Make sure that all structs have at least one field; this avoids
|
||||||
# potential issues with attempting to malloc space for zero-length
|
# potential issues with attempting to malloc space for zero-length
|
||||||
# structs in C, and also incompatibility with C++ (where an empty
|
# structs in C, and also incompatibility with C++ (where an empty
|
||||||
# struct is size 1).
|
# struct is size 1).
|
||||||
if not (base and base.members) and not members:
|
if not (base and base.members) and not members and not variants:
|
||||||
ret += mcgen('''
|
ret += mcgen('''
|
||||||
char qapi_dummy_field_for_empty_struct;
|
char qapi_dummy_field_for_empty_struct;
|
||||||
''')
|
''')
|
||||||
@ -108,49 +101,7 @@ static inline %(base)s *qapi_%(c_name)s_base(const %(c_name)s *obj)
|
|||||||
c_name=c_name(name), base=base.c_name())
|
c_name=c_name(name), base=base.c_name())
|
||||||
|
|
||||||
|
|
||||||
def gen_alternate_qtypes_decl(name):
|
def gen_variants(variants):
|
||||||
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_union(name, base, variants):
|
|
||||||
ret = mcgen('''
|
|
||||||
|
|
||||||
struct %(c_name)s {
|
|
||||||
''',
|
|
||||||
c_name=c_name(name))
|
|
||||||
if base:
|
|
||||||
ret += gen_struct_fields([], base)
|
|
||||||
else:
|
|
||||||
ret += gen_struct_field(variants.tag_member)
|
|
||||||
|
|
||||||
# FIXME: What purpose does data serve, besides preventing a union that
|
# 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
|
# has a branch named 'data'? We use it in qapi-visit.py to decide
|
||||||
# whether to bypass the switch statement if visiting the discriminator
|
# whether to bypass the switch statement if visiting the discriminator
|
||||||
@ -159,7 +110,7 @@ struct %(c_name)s {
|
|||||||
# should not be any data leaks even without a data pointer. Or, if
|
# should not be any data leaks even without a data pointer. Or, if
|
||||||
# 'data' is merely added to guarantee we don't have an empty union,
|
# 'data' is merely added to guarantee we don't have an empty union,
|
||||||
# shouldn't we enforce that at .json parse time?
|
# shouldn't we enforce that at .json parse time?
|
||||||
ret += mcgen('''
|
ret = mcgen('''
|
||||||
union { /* union tag is @%(c_name)s */
|
union { /* union tag is @%(c_name)s */
|
||||||
void *data;
|
void *data;
|
||||||
''',
|
''',
|
||||||
@ -176,7 +127,6 @@ struct %(c_name)s {
|
|||||||
|
|
||||||
ret += mcgen('''
|
ret += mcgen('''
|
||||||
} u;
|
} u;
|
||||||
};
|
|
||||||
''')
|
''')
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
@ -218,21 +168,17 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
|
|||||||
self.decl = None
|
self.decl = None
|
||||||
self.defn = None
|
self.defn = None
|
||||||
self._fwdecl = None
|
self._fwdecl = None
|
||||||
self._fwdefn = None
|
|
||||||
self._btin = None
|
self._btin = None
|
||||||
|
|
||||||
def visit_begin(self, schema):
|
def visit_begin(self, schema):
|
||||||
self.decl = ''
|
self.decl = ''
|
||||||
self.defn = ''
|
self.defn = ''
|
||||||
self._fwdecl = ''
|
self._fwdecl = ''
|
||||||
self._fwdefn = ''
|
|
||||||
self._btin = guardstart('QAPI_TYPES_BUILTIN')
|
self._btin = guardstart('QAPI_TYPES_BUILTIN')
|
||||||
|
|
||||||
def visit_end(self):
|
def visit_end(self):
|
||||||
self.decl = self._fwdecl + self.decl
|
self.decl = self._fwdecl + self.decl
|
||||||
self._fwdecl = None
|
self._fwdecl = None
|
||||||
self.defn = self._fwdefn + self.defn
|
|
||||||
self._fwdefn = None
|
|
||||||
# To avoid header dependency hell, we always generate
|
# To avoid header dependency hell, we always generate
|
||||||
# declarations for built-in types in our header files and
|
# declarations for built-in types in our header files and
|
||||||
# simply guard them. See also do_builtins (command line
|
# simply guard them. See also do_builtins (command line
|
||||||
@ -251,8 +197,15 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
|
|||||||
self.defn += gen_type_cleanup(name)
|
self.defn += gen_type_cleanup(name)
|
||||||
|
|
||||||
def visit_enum_type(self, name, info, values, prefix):
|
def visit_enum_type(self, name, info, 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._fwdecl += gen_enum(name, values, prefix)
|
||||||
self._fwdefn += gen_enum_lookup(name, values, prefix)
|
self.defn += gen_enum_lookup(name, values, prefix)
|
||||||
|
|
||||||
def visit_array_type(self, name, info, element_type):
|
def visit_array_type(self, name, info, element_type):
|
||||||
if isinstance(element_type, QAPISchemaBuiltinType):
|
if isinstance(element_type, QAPISchemaBuiltinType):
|
||||||
@ -268,20 +221,14 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
|
|||||||
|
|
||||||
def visit_object_type(self, name, info, base, members, variants):
|
def visit_object_type(self, name, info, base, members, variants):
|
||||||
self._fwdecl += gen_fwd_object_or_array(name)
|
self._fwdecl += gen_fwd_object_or_array(name)
|
||||||
if variants:
|
self.decl += gen_object(name, base, members, variants)
|
||||||
assert not members # not implemented
|
|
||||||
self.decl += gen_union(name, base, variants)
|
|
||||||
else:
|
|
||||||
self.decl += gen_struct(name, base, members)
|
|
||||||
if base:
|
if base:
|
||||||
self.decl += gen_upcast(name, base)
|
self.decl += gen_upcast(name, base)
|
||||||
self._gen_type_cleanup(name)
|
self._gen_type_cleanup(name)
|
||||||
|
|
||||||
def visit_alternate_type(self, name, info, variants):
|
def visit_alternate_type(self, name, info, variants):
|
||||||
self._fwdecl += gen_fwd_object_or_array(name)
|
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_union(name, None, variants)
|
|
||||||
self.decl += gen_alternate_qtypes_decl(name)
|
|
||||||
self._gen_type_cleanup(name)
|
self._gen_type_cleanup(name)
|
||||||
|
|
||||||
# If you link code generated from multiple schemata, you want only one
|
# If you link code generated from multiple schemata, you want only one
|
||||||
@ -338,10 +285,11 @@ fdef.write(mcgen('''
|
|||||||
''',
|
''',
|
||||||
prefix=prefix))
|
prefix=prefix))
|
||||||
|
|
||||||
|
# To avoid circular headers, use only typedefs.h here, not qobject.h
|
||||||
fdecl.write(mcgen('''
|
fdecl.write(mcgen('''
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "qapi/qmp/qobject.h"
|
#include "qemu/typedefs.h"
|
||||||
'''))
|
'''))
|
||||||
|
|
||||||
schema = QAPISchema(input_file)
|
schema = QAPISchema(input_file)
|
||||||
|
@ -172,6 +172,7 @@ out:
|
|||||||
|
|
||||||
|
|
||||||
def gen_visit_enum(name):
|
def gen_visit_enum(name):
|
||||||
|
# FIXME cast from enum *obj to int * invalidly assumes enum is int
|
||||||
return mcgen('''
|
return mcgen('''
|
||||||
|
|
||||||
void visit_type_%(c_name)s(Visitor *v, %(c_name)s *obj, const char *name, Error **errp)
|
void visit_type_%(c_name)s(Visitor *v, %(c_name)s *obj, const char *name, Error **errp)
|
||||||
@ -183,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):
|
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('''
|
ret = mcgen('''
|
||||||
|
|
||||||
void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, Error **errp)
|
void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, Error **errp)
|
||||||
@ -193,13 +199,13 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, Error
|
|||||||
if (err) {
|
if (err) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
visit_get_next_type(v, (int*) &(*obj)->type, %(c_name)s_qtypes, name, &err);
|
visit_get_next_type(v, &(*obj)->type, %(promote_int)s, name, &err);
|
||||||
if (err) {
|
if (err) {
|
||||||
goto out_obj;
|
goto out_obj;
|
||||||
}
|
}
|
||||||
switch ((*obj)->type) {
|
switch ((*obj)->type) {
|
||||||
''',
|
''',
|
||||||
c_name=c_name(name))
|
c_name=c_name(name), promote_int=promote_int)
|
||||||
|
|
||||||
for var in variants.variants:
|
for var in variants.variants:
|
||||||
ret += mcgen('''
|
ret += mcgen('''
|
||||||
@ -207,14 +213,14 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, Error
|
|||||||
visit_type_%(c_type)s(v, &(*obj)->u.%(c_name)s, name, &err);
|
visit_type_%(c_type)s(v, &(*obj)->u.%(c_name)s, name, &err);
|
||||||
break;
|
break;
|
||||||
''',
|
''',
|
||||||
case=c_enum_const(variants.tag_member.type.name,
|
case=var.type.alternate_qtype(),
|
||||||
var.name),
|
|
||||||
c_type=var.type.c_name(),
|
c_type=var.type.c_name(),
|
||||||
c_name=c_name(var.name))
|
c_name=c_name(var.name))
|
||||||
|
|
||||||
ret += mcgen('''
|
ret += mcgen('''
|
||||||
default:
|
default:
|
||||||
abort();
|
error_setg(&err, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
|
||||||
|
"%(name)s");
|
||||||
}
|
}
|
||||||
out_obj:
|
out_obj:
|
||||||
error_propagate(errp, err);
|
error_propagate(errp, err);
|
||||||
@ -223,7 +229,8 @@ out_obj:
|
|||||||
out:
|
out:
|
||||||
error_propagate(errp, err);
|
error_propagate(errp, err);
|
||||||
}
|
}
|
||||||
''')
|
''',
|
||||||
|
name=name)
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@ -347,6 +354,13 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
|
|||||||
isinstance(entity, QAPISchemaObjectType))
|
isinstance(entity, QAPISchemaObjectType))
|
||||||
|
|
||||||
def visit_enum_type(self, name, info, values, prefix):
|
def visit_enum_type(self, name, info, values, prefix):
|
||||||
|
# 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.decl += gen_visit_decl(name, scalar=True)
|
||||||
self.defn += gen_visit_enum(name)
|
self.defn += gen_visit_enum(name)
|
||||||
|
|
||||||
@ -364,7 +378,10 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
|
|||||||
def visit_object_type(self, name, info, base, members, variants):
|
def visit_object_type(self, name, info, base, members, variants):
|
||||||
self.decl += gen_visit_decl(name)
|
self.decl += gen_visit_decl(name)
|
||||||
if variants:
|
if variants:
|
||||||
assert not members # not implemented
|
if members:
|
||||||
|
# Members other than variants.tag_member not implemented
|
||||||
|
assert len(members) == 1
|
||||||
|
assert members[0] == variants.tag_member
|
||||||
self.defn += gen_visit_union(name, base, variants)
|
self.defn += gen_visit_union(name, base, variants)
|
||||||
else:
|
else:
|
||||||
self.defn += gen_visit_struct(name, base, members)
|
self.defn += gen_visit_struct(name, base, members)
|
||||||
@ -427,6 +444,7 @@ fdef.write(mcgen('''
|
|||||||
|
|
||||||
fdecl.write(mcgen('''
|
fdecl.write(mcgen('''
|
||||||
#include "qapi/visitor.h"
|
#include "qapi/visitor.h"
|
||||||
|
#include "qapi/qmp/qerror.h"
|
||||||
#include "%(prefix)sqapi-types.h"
|
#include "%(prefix)sqapi-types.h"
|
||||||
|
|
||||||
''',
|
''',
|
||||||
|
295
scripts/qapi.py
295
scripts/qapi.py
@ -33,7 +33,8 @@ builtin_types = {
|
|||||||
'uint32': 'QTYPE_QINT',
|
'uint32': 'QTYPE_QINT',
|
||||||
'uint64': 'QTYPE_QINT',
|
'uint64': 'QTYPE_QINT',
|
||||||
'size': 'QTYPE_QINT',
|
'size': 'QTYPE_QINT',
|
||||||
'any': None, # any qtype_code possible, actually
|
'any': None, # any QType possible, actually
|
||||||
|
'QType': 'QTYPE_QSTRING',
|
||||||
}
|
}
|
||||||
|
|
||||||
# Whitelist of commands allowed to return a non-dictionary
|
# Whitelist of commands allowed to return a non-dictionary
|
||||||
@ -58,6 +59,20 @@ returns_whitelist = [
|
|||||||
'guest-sync-delimited',
|
'guest-sync-delimited',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Whitelist of entities allowed to violate case conventions
|
||||||
|
case_whitelist = [
|
||||||
|
# From QMP:
|
||||||
|
'ACPISlotType', # DIMM, visible through query-acpi-ospm-status
|
||||||
|
'CpuInfoBase', # CPU, visible through query-cpu
|
||||||
|
'CpuInfoMIPS', # PC, visible through query-cpu
|
||||||
|
'CpuInfoTricore', # PC, visible through query-cpu
|
||||||
|
'InputAxis', # TODO: drop when x-input-send-event is fixed
|
||||||
|
'InputButton', # TODO: drop when x-input-send-event is fixed
|
||||||
|
'QapiErrorClass', # all members, visible through errors
|
||||||
|
'UuidInfo', # UUID, visible through query-uuid
|
||||||
|
'X86CPURegister32', # all members, visible indirectly through qom-get
|
||||||
|
]
|
||||||
|
|
||||||
enum_types = []
|
enum_types = []
|
||||||
struct_types = []
|
struct_types = []
|
||||||
union_types = []
|
union_types = []
|
||||||
@ -353,9 +368,11 @@ def discriminator_find_enum_define(expr):
|
|||||||
return find_enum(discriminator_type)
|
return find_enum(discriminator_type)
|
||||||
|
|
||||||
|
|
||||||
# FIXME should enforce "other than downstream extensions [...], all
|
# Names must be letters, numbers, -, and _. They must start with letter,
|
||||||
# names should begin with a letter".
|
# except for downstream extensions which must start with __RFQDN_.
|
||||||
valid_name = re.compile('^[a-zA-Z_][a-zA-Z0-9_.-]*$')
|
# Dots are only valid in the downstream extension prefix.
|
||||||
|
valid_name = re.compile('^(__[a-zA-Z0-9.-]+_)?'
|
||||||
|
'[a-zA-Z][a-zA-Z0-9_-]*$')
|
||||||
|
|
||||||
|
|
||||||
def check_name(expr_info, source, name, allow_optional=False,
|
def check_name(expr_info, source, name, allow_optional=False,
|
||||||
@ -374,8 +391,8 @@ def check_name(expr_info, source, name, allow_optional=False,
|
|||||||
% (source, name))
|
% (source, name))
|
||||||
# Enum members can start with a digit, because the generated C
|
# Enum members can start with a digit, because the generated C
|
||||||
# code always prefixes it with the enum name
|
# code always prefixes it with the enum name
|
||||||
if enum_member:
|
if enum_member and membername[0].isdigit():
|
||||||
membername = '_' + membername
|
membername = 'D' + membername
|
||||||
# Reserve the entire 'q_' namespace for c_name()
|
# Reserve the entire 'q_' namespace for c_name()
|
||||||
if not valid_name.match(membername) or \
|
if not valid_name.match(membername) or \
|
||||||
c_name(membername, False).startswith('q_'):
|
c_name(membername, False).startswith('q_'):
|
||||||
@ -502,21 +519,6 @@ def check_type(expr_info, source, value, allow_array=False,
|
|||||||
'enum'])
|
'enum'])
|
||||||
|
|
||||||
|
|
||||||
def check_member_clash(expr_info, base_name, data, source=""):
|
|
||||||
base = find_struct(base_name)
|
|
||||||
assert base
|
|
||||||
base_members = base['data']
|
|
||||||
for key in data.keys():
|
|
||||||
if key.startswith('*'):
|
|
||||||
key = key[1:]
|
|
||||||
if key in base_members or "*" + key in base_members:
|
|
||||||
raise QAPIExprError(expr_info,
|
|
||||||
"Member name '%s'%s clashes with base '%s'"
|
|
||||||
% (key, source, base_name))
|
|
||||||
if base.get('base'):
|
|
||||||
check_member_clash(expr_info, base['base'], data, source)
|
|
||||||
|
|
||||||
|
|
||||||
def check_command(expr, expr_info):
|
def check_command(expr, expr_info):
|
||||||
name = expr['command']
|
name = expr['command']
|
||||||
|
|
||||||
@ -535,8 +537,6 @@ def check_event(expr, expr_info):
|
|||||||
global events
|
global events
|
||||||
name = expr['event']
|
name = expr['event']
|
||||||
|
|
||||||
if name.upper() == 'MAX':
|
|
||||||
raise QAPIExprError(expr_info, "Event name 'MAX' cannot be created")
|
|
||||||
events.append(name)
|
events.append(name)
|
||||||
check_type(expr_info, "'data' for event '%s'" % name,
|
check_type(expr_info, "'data' for event '%s'" % name,
|
||||||
expr.get('data'), allow_dict=True, allow_optional=True,
|
expr.get('data'), allow_dict=True, allow_optional=True,
|
||||||
@ -548,8 +548,6 @@ def check_union(expr, expr_info):
|
|||||||
base = expr.get('base')
|
base = expr.get('base')
|
||||||
discriminator = expr.get('discriminator')
|
discriminator = expr.get('discriminator')
|
||||||
members = expr['data']
|
members = expr['data']
|
||||||
values = {'MAX': '(automatic)', 'KIND': '(automatic)',
|
|
||||||
'TYPE': '(automatic)'}
|
|
||||||
|
|
||||||
# Two types of unions, determined by discriminator.
|
# Two types of unions, determined by discriminator.
|
||||||
|
|
||||||
@ -596,59 +594,29 @@ def check_union(expr, expr_info):
|
|||||||
for (key, value) in members.items():
|
for (key, value) in members.items():
|
||||||
check_name(expr_info, "Member of union '%s'" % name, key)
|
check_name(expr_info, "Member of union '%s'" % name, key)
|
||||||
|
|
||||||
# Each value must name a known type; furthermore, in flat unions,
|
# Each value must name a known type
|
||||||
# branches must be a struct with no overlapping member names
|
|
||||||
check_type(expr_info, "Member '%s' of union '%s'" % (key, name),
|
check_type(expr_info, "Member '%s' of union '%s'" % (key, name),
|
||||||
value, allow_array=not base, allow_metas=allow_metas)
|
value, allow_array=not base, allow_metas=allow_metas)
|
||||||
if base:
|
|
||||||
branch_struct = find_struct(value)
|
|
||||||
assert branch_struct
|
|
||||||
check_member_clash(expr_info, base, branch_struct['data'],
|
|
||||||
" of branch '%s'" % key)
|
|
||||||
|
|
||||||
# If the discriminator names an enum type, then all members
|
# If the discriminator names an enum type, then all members
|
||||||
# of 'data' must also be members of the enum type, which in turn
|
# of 'data' must also be members of the enum type.
|
||||||
# must not collide with the discriminator name.
|
|
||||||
if enum_define:
|
if enum_define:
|
||||||
if key not in enum_define['enum_values']:
|
if key not in enum_define['enum_values']:
|
||||||
raise QAPIExprError(expr_info,
|
raise QAPIExprError(expr_info,
|
||||||
"Discriminator value '%s' is not found in "
|
"Discriminator value '%s' is not found in "
|
||||||
"enum '%s'" %
|
"enum '%s'" %
|
||||||
(key, enum_define["enum_name"]))
|
(key, enum_define["enum_name"]))
|
||||||
if discriminator in enum_define['enum_values']:
|
|
||||||
raise QAPIExprError(expr_info,
|
|
||||||
"Discriminator name '%s' collides with "
|
|
||||||
"enum value in '%s'" %
|
|
||||||
(discriminator, enum_define["enum_name"]))
|
|
||||||
|
|
||||||
# Otherwise, check for conflicts in the generated enum
|
|
||||||
else:
|
|
||||||
c_key = camel_to_upper(key)
|
|
||||||
if c_key in values:
|
|
||||||
raise QAPIExprError(expr_info,
|
|
||||||
"Union '%s' member '%s' clashes with '%s'"
|
|
||||||
% (name, key, values[c_key]))
|
|
||||||
values[c_key] = key
|
|
||||||
|
|
||||||
|
|
||||||
def check_alternate(expr, expr_info):
|
def check_alternate(expr, expr_info):
|
||||||
name = expr['alternate']
|
name = expr['alternate']
|
||||||
members = expr['data']
|
members = expr['data']
|
||||||
values = {'MAX': '(automatic)'}
|
|
||||||
types_seen = {}
|
types_seen = {}
|
||||||
|
|
||||||
# Check every branch
|
# Check every branch
|
||||||
for (key, value) in members.items():
|
for (key, value) in members.items():
|
||||||
check_name(expr_info, "Member of alternate '%s'" % name, key)
|
check_name(expr_info, "Member of alternate '%s'" % name, key)
|
||||||
|
|
||||||
# Check for conflicts in the generated enum
|
|
||||||
c_key = camel_to_upper(key)
|
|
||||||
if c_key in values:
|
|
||||||
raise QAPIExprError(expr_info,
|
|
||||||
"Alternate '%s' member '%s' clashes with '%s'"
|
|
||||||
% (name, key, values[c_key]))
|
|
||||||
values[c_key] = key
|
|
||||||
|
|
||||||
# Ensure alternates have no type conflicts.
|
# Ensure alternates have no type conflicts.
|
||||||
check_type(expr_info, "Member '%s' of alternate '%s'" % (key, name),
|
check_type(expr_info, "Member '%s' of alternate '%s'" % (key, name),
|
||||||
value,
|
value,
|
||||||
@ -667,7 +635,6 @@ def check_enum(expr, expr_info):
|
|||||||
name = expr['enum']
|
name = expr['enum']
|
||||||
members = expr.get('data')
|
members = expr.get('data')
|
||||||
prefix = expr.get('prefix')
|
prefix = expr.get('prefix')
|
||||||
values = {'MAX': '(automatic)'}
|
|
||||||
|
|
||||||
if not isinstance(members, list):
|
if not isinstance(members, list):
|
||||||
raise QAPIExprError(expr_info,
|
raise QAPIExprError(expr_info,
|
||||||
@ -678,12 +645,6 @@ def check_enum(expr, expr_info):
|
|||||||
for member in members:
|
for member in members:
|
||||||
check_name(expr_info, "Member of enum '%s'" % name, member,
|
check_name(expr_info, "Member of enum '%s'" % name, member,
|
||||||
enum_member=True)
|
enum_member=True)
|
||||||
key = camel_to_upper(member)
|
|
||||||
if key in values:
|
|
||||||
raise QAPIExprError(expr_info,
|
|
||||||
"Enum '%s' member '%s' clashes with '%s'"
|
|
||||||
% (name, member, values[key]))
|
|
||||||
values[key] = member
|
|
||||||
|
|
||||||
|
|
||||||
def check_struct(expr, expr_info):
|
def check_struct(expr, expr_info):
|
||||||
@ -694,8 +655,6 @@ def check_struct(expr, expr_info):
|
|||||||
allow_dict=True, allow_optional=True)
|
allow_dict=True, allow_optional=True)
|
||||||
check_type(expr_info, "'base' for struct '%s'" % name, expr.get('base'),
|
check_type(expr_info, "'base' for struct '%s'" % name, expr.get('base'),
|
||||||
allow_metas=['struct'])
|
allow_metas=['struct'])
|
||||||
if expr.get('base'):
|
|
||||||
check_member_clash(expr_info, expr['base'], expr['data'])
|
|
||||||
|
|
||||||
|
|
||||||
def check_keys(expr_elem, meta, required, optional=[]):
|
def check_keys(expr_elem, meta, required, optional=[]):
|
||||||
@ -907,13 +866,16 @@ class QAPISchemaEnumType(QAPISchemaType):
|
|||||||
def __init__(self, name, info, values, prefix):
|
def __init__(self, name, info, values, prefix):
|
||||||
QAPISchemaType.__init__(self, name, info)
|
QAPISchemaType.__init__(self, name, info)
|
||||||
for v in values:
|
for v in values:
|
||||||
assert isinstance(v, str)
|
assert isinstance(v, QAPISchemaMember)
|
||||||
|
v.set_owner(name)
|
||||||
assert prefix is None or isinstance(prefix, str)
|
assert prefix is None or isinstance(prefix, str)
|
||||||
self.values = values
|
self.values = values
|
||||||
self.prefix = prefix
|
self.prefix = prefix
|
||||||
|
|
||||||
def check(self, schema):
|
def check(self, schema):
|
||||||
assert len(set(self.values)) == len(self.values)
|
seen = {}
|
||||||
|
for v in self.values:
|
||||||
|
v.check_clash(self.info, seen)
|
||||||
|
|
||||||
def is_implicit(self):
|
def is_implicit(self):
|
||||||
# See QAPISchema._make_implicit_enum_type()
|
# See QAPISchema._make_implicit_enum_type()
|
||||||
@ -922,8 +884,11 @@ class QAPISchemaEnumType(QAPISchemaType):
|
|||||||
def c_type(self, is_param=False):
|
def c_type(self, is_param=False):
|
||||||
return c_name(self.name)
|
return c_name(self.name)
|
||||||
|
|
||||||
|
def member_names(self):
|
||||||
|
return [v.name for v in self.values]
|
||||||
|
|
||||||
def c_null(self):
|
def c_null(self):
|
||||||
return c_enum_const(self.name, (self.values + ['MAX'])[0],
|
return c_enum_const(self.name, (self.member_names() + ['_MAX'])[0],
|
||||||
self.prefix)
|
self.prefix)
|
||||||
|
|
||||||
def json_type(self):
|
def json_type(self):
|
||||||
@ -931,7 +896,7 @@ class QAPISchemaEnumType(QAPISchemaType):
|
|||||||
|
|
||||||
def visit(self, visitor):
|
def visit(self, visitor):
|
||||||
visitor.visit_enum_type(self.name, self.info,
|
visitor.visit_enum_type(self.name, self.info,
|
||||||
self.values, self.prefix)
|
self.member_names(), self.prefix)
|
||||||
|
|
||||||
|
|
||||||
class QAPISchemaArrayType(QAPISchemaType):
|
class QAPISchemaArrayType(QAPISchemaType):
|
||||||
@ -957,12 +922,17 @@ class QAPISchemaArrayType(QAPISchemaType):
|
|||||||
|
|
||||||
class QAPISchemaObjectType(QAPISchemaType):
|
class QAPISchemaObjectType(QAPISchemaType):
|
||||||
def __init__(self, name, info, base, local_members, variants):
|
def __init__(self, name, info, base, local_members, variants):
|
||||||
|
# struct has local_members, optional base, and no variants
|
||||||
|
# flat union has base, variants, and no local_members
|
||||||
|
# simple union has local_members, variants, and no base
|
||||||
QAPISchemaType.__init__(self, name, info)
|
QAPISchemaType.__init__(self, name, info)
|
||||||
assert base is None or isinstance(base, str)
|
assert base is None or isinstance(base, str)
|
||||||
for m in local_members:
|
for m in local_members:
|
||||||
assert isinstance(m, QAPISchemaObjectTypeMember)
|
assert isinstance(m, QAPISchemaObjectTypeMember)
|
||||||
assert (variants is None or
|
m.set_owner(name)
|
||||||
isinstance(variants, QAPISchemaObjectTypeVariants))
|
if variants is not None:
|
||||||
|
assert isinstance(variants, QAPISchemaObjectTypeVariants)
|
||||||
|
variants.set_owner(name)
|
||||||
self._base_name = base
|
self._base_name = base
|
||||||
self.base = None
|
self.base = None
|
||||||
self.local_members = local_members
|
self.local_members = local_members
|
||||||
@ -970,27 +940,34 @@ class QAPISchemaObjectType(QAPISchemaType):
|
|||||||
self.members = None
|
self.members = None
|
||||||
|
|
||||||
def check(self, schema):
|
def check(self, schema):
|
||||||
assert self.members is not False # not running in cycles
|
if self.members is False: # check for cycles
|
||||||
|
raise QAPIExprError(self.info,
|
||||||
|
"Object %s contains itself" % self.name)
|
||||||
if self.members:
|
if self.members:
|
||||||
return
|
return
|
||||||
self.members = False # mark as being checked
|
self.members = False # mark as being checked
|
||||||
|
seen = OrderedDict()
|
||||||
if self._base_name:
|
if self._base_name:
|
||||||
self.base = schema.lookup_type(self._base_name)
|
self.base = schema.lookup_type(self._base_name)
|
||||||
assert isinstance(self.base, QAPISchemaObjectType)
|
assert isinstance(self.base, QAPISchemaObjectType)
|
||||||
assert not self.base.variants # not implemented
|
|
||||||
self.base.check(schema)
|
self.base.check(schema)
|
||||||
members = list(self.base.members)
|
self.base.check_clash(schema, self.info, seen)
|
||||||
else:
|
|
||||||
members = []
|
|
||||||
seen = {}
|
|
||||||
for m in members:
|
|
||||||
assert c_name(m.name) not in seen
|
|
||||||
seen[m.name] = m
|
|
||||||
for m in self.local_members:
|
for m in self.local_members:
|
||||||
m.check(schema, members, seen)
|
m.check(schema)
|
||||||
|
m.check_clash(self.info, seen)
|
||||||
|
self.members = seen.values()
|
||||||
if self.variants:
|
if self.variants:
|
||||||
self.variants.check(schema, members, seen)
|
self.variants.check(schema, seen)
|
||||||
self.members = members
|
assert self.variants.tag_member in self.members
|
||||||
|
self.variants.check_clash(schema, self.info, seen)
|
||||||
|
|
||||||
|
# Check that the members of this type do not cause duplicate JSON fields,
|
||||||
|
# and update seen to track the members seen so far. Report any errors
|
||||||
|
# on behalf of info, which is not necessarily self.info
|
||||||
|
def check_clash(self, schema, info, seen):
|
||||||
|
assert not self.variants # not implemented
|
||||||
|
for m in self.members:
|
||||||
|
m.check_clash(info, seen)
|
||||||
|
|
||||||
def is_implicit(self):
|
def is_implicit(self):
|
||||||
# See QAPISchema._make_implicit_object_type()
|
# See QAPISchema._make_implicit_object_type()
|
||||||
@ -1014,22 +991,63 @@ class QAPISchemaObjectType(QAPISchemaType):
|
|||||||
self.members, self.variants)
|
self.members, self.variants)
|
||||||
|
|
||||||
|
|
||||||
class QAPISchemaObjectTypeMember(object):
|
class QAPISchemaMember(object):
|
||||||
def __init__(self, name, typ, optional):
|
role = 'member'
|
||||||
|
|
||||||
|
def __init__(self, name):
|
||||||
assert isinstance(name, str)
|
assert isinstance(name, str)
|
||||||
|
self.name = name
|
||||||
|
self.owner = None
|
||||||
|
|
||||||
|
def set_owner(self, name):
|
||||||
|
assert not self.owner
|
||||||
|
self.owner = name
|
||||||
|
|
||||||
|
def check_clash(self, info, seen):
|
||||||
|
cname = c_name(self.name)
|
||||||
|
if cname.lower() != cname and self.owner not in case_whitelist:
|
||||||
|
raise QAPIExprError(info,
|
||||||
|
"%s should not use uppercase" % self.describe())
|
||||||
|
if cname in seen:
|
||||||
|
raise QAPIExprError(info,
|
||||||
|
"%s collides with %s"
|
||||||
|
% (self.describe(), seen[cname].describe()))
|
||||||
|
seen[cname] = self
|
||||||
|
|
||||||
|
def _pretty_owner(self):
|
||||||
|
owner = self.owner
|
||||||
|
if owner.startswith(':obj-'):
|
||||||
|
# See QAPISchema._make_implicit_object_type() - reverse the
|
||||||
|
# mapping there to create a nice human-readable description
|
||||||
|
owner = owner[5:]
|
||||||
|
if owner.endswith('-arg'):
|
||||||
|
return '(parameter of %s)' % owner[:-4]
|
||||||
|
else:
|
||||||
|
assert owner.endswith('-wrapper')
|
||||||
|
# Unreachable and not implemented
|
||||||
|
assert False
|
||||||
|
if owner.endswith('Kind'):
|
||||||
|
# See QAPISchema._make_implicit_enum_type()
|
||||||
|
return '(branch of %s)' % owner[:-4]
|
||||||
|
return '(%s of %s)' % (self.role, owner)
|
||||||
|
|
||||||
|
def describe(self):
|
||||||
|
return "'%s' %s" % (self.name, self._pretty_owner())
|
||||||
|
|
||||||
|
|
||||||
|
class QAPISchemaObjectTypeMember(QAPISchemaMember):
|
||||||
|
def __init__(self, name, typ, optional):
|
||||||
|
QAPISchemaMember.__init__(self, name)
|
||||||
assert isinstance(typ, str)
|
assert isinstance(typ, str)
|
||||||
assert isinstance(optional, bool)
|
assert isinstance(optional, bool)
|
||||||
self.name = name
|
|
||||||
self._type_name = typ
|
self._type_name = typ
|
||||||
self.type = None
|
self.type = None
|
||||||
self.optional = optional
|
self.optional = optional
|
||||||
|
|
||||||
def check(self, schema, all_members, seen):
|
def check(self, schema):
|
||||||
assert self.name not in seen
|
assert self.owner
|
||||||
self.type = schema.lookup_type(self._type_name)
|
self.type = schema.lookup_type(self._type_name)
|
||||||
assert self.type
|
assert self.type
|
||||||
all_members.append(self)
|
|
||||||
seen[self.name] = self
|
|
||||||
|
|
||||||
|
|
||||||
class QAPISchemaObjectTypeVariants(object):
|
class QAPISchemaObjectTypeVariants(object):
|
||||||
@ -1047,25 +1065,38 @@ class QAPISchemaObjectTypeVariants(object):
|
|||||||
self.tag_member = tag_member
|
self.tag_member = tag_member
|
||||||
self.variants = variants
|
self.variants = variants
|
||||||
|
|
||||||
def check(self, schema, members, seen):
|
def set_owner(self, name):
|
||||||
if self.tag_name:
|
for v in self.variants:
|
||||||
self.tag_member = seen[self.tag_name]
|
v.set_owner(name)
|
||||||
else:
|
|
||||||
self.tag_member.check(schema, members, seen)
|
def check(self, schema, seen):
|
||||||
|
if not self.tag_member: # flat union
|
||||||
|
self.tag_member = seen[c_name(self.tag_name)]
|
||||||
|
assert self.tag_name == self.tag_member.name
|
||||||
assert isinstance(self.tag_member.type, QAPISchemaEnumType)
|
assert isinstance(self.tag_member.type, QAPISchemaEnumType)
|
||||||
for v in self.variants:
|
for v in self.variants:
|
||||||
vseen = dict(seen)
|
v.check(schema)
|
||||||
v.check(schema, self.tag_member.type, vseen)
|
# 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.member_names()
|
||||||
|
assert isinstance(v.type, QAPISchemaObjectType)
|
||||||
|
v.type.check(schema)
|
||||||
|
|
||||||
|
def check_clash(self, schema, info, seen):
|
||||||
|
for v in self.variants:
|
||||||
|
# Reset seen map for each variant, since qapi names from one
|
||||||
|
# branch do not affect another branch
|
||||||
|
assert isinstance(v.type, QAPISchemaObjectType)
|
||||||
|
v.type.check_clash(schema, info, dict(seen))
|
||||||
|
|
||||||
|
|
||||||
class QAPISchemaObjectTypeVariant(QAPISchemaObjectTypeMember):
|
class QAPISchemaObjectTypeVariant(QAPISchemaObjectTypeMember):
|
||||||
|
role = 'branch'
|
||||||
|
|
||||||
def __init__(self, name, typ):
|
def __init__(self, name, typ):
|
||||||
QAPISchemaObjectTypeMember.__init__(self, name, typ, False)
|
QAPISchemaObjectTypeMember.__init__(self, name, typ, False)
|
||||||
|
|
||||||
def check(self, schema, tag_type, seen):
|
|
||||||
QAPISchemaObjectTypeMember.check(self, schema, [], seen)
|
|
||||||
assert self.name in tag_type.values
|
|
||||||
|
|
||||||
# This function exists to support ugly simple union special cases
|
# This function exists to support ugly simple union special cases
|
||||||
# TODO get rid of them, and drop the function
|
# TODO get rid of them, and drop the function
|
||||||
def simple_union_type(self):
|
def simple_union_type(self):
|
||||||
@ -1082,10 +1113,20 @@ class QAPISchemaAlternateType(QAPISchemaType):
|
|||||||
QAPISchemaType.__init__(self, name, info)
|
QAPISchemaType.__init__(self, name, info)
|
||||||
assert isinstance(variants, QAPISchemaObjectTypeVariants)
|
assert isinstance(variants, QAPISchemaObjectTypeVariants)
|
||||||
assert not variants.tag_name
|
assert not variants.tag_name
|
||||||
|
variants.set_owner(name)
|
||||||
|
variants.tag_member.set_owner(self.name)
|
||||||
self.variants = variants
|
self.variants = variants
|
||||||
|
|
||||||
def check(self, schema):
|
def check(self, schema):
|
||||||
self.variants.check(schema, [], {})
|
self.variants.tag_member.check(schema)
|
||||||
|
# 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):
|
def json_type(self):
|
||||||
return 'value'
|
return 'value'
|
||||||
@ -1196,10 +1237,20 @@ class QAPISchema(object):
|
|||||||
self.the_empty_object_type = QAPISchemaObjectType(':empty', None, None,
|
self.the_empty_object_type = QAPISchemaObjectType(':empty', None, None,
|
||||||
[], None)
|
[], None)
|
||||||
self._def_entity(self.the_empty_object_type)
|
self._def_entity(self.the_empty_object_type)
|
||||||
|
qtype_values = self._make_enum_members(['none', 'qnull', 'qint',
|
||||||
|
'qstring', 'qdict', 'qlist',
|
||||||
|
'qfloat', 'qbool'])
|
||||||
|
self._def_entity(QAPISchemaEnumType('QType', None, qtype_values,
|
||||||
|
'QTYPE'))
|
||||||
|
|
||||||
|
def _make_enum_members(self, values):
|
||||||
|
return [QAPISchemaMember(v) for v in values]
|
||||||
|
|
||||||
def _make_implicit_enum_type(self, name, info, values):
|
def _make_implicit_enum_type(self, name, info, values):
|
||||||
|
# See also QAPISchemaObjectTypeMember._pretty_owner()
|
||||||
name = name + 'Kind' # Use namespace reserved by add_name()
|
name = name + 'Kind' # Use namespace reserved by add_name()
|
||||||
self._def_entity(QAPISchemaEnumType(name, info, values, None))
|
self._def_entity(QAPISchemaEnumType(
|
||||||
|
name, info, self._make_enum_members(values), None))
|
||||||
return name
|
return name
|
||||||
|
|
||||||
def _make_array_type(self, element_type, info):
|
def _make_array_type(self, element_type, info):
|
||||||
@ -1211,6 +1262,7 @@ class QAPISchema(object):
|
|||||||
def _make_implicit_object_type(self, name, info, role, members):
|
def _make_implicit_object_type(self, name, info, role, members):
|
||||||
if not members:
|
if not members:
|
||||||
return None
|
return None
|
||||||
|
# See also QAPISchemaObjectTypeMember._pretty_owner()
|
||||||
name = ':obj-%s-%s' % (name, role)
|
name = ':obj-%s-%s' % (name, role)
|
||||||
if not self.lookup_entity(name, QAPISchemaObjectType):
|
if not self.lookup_entity(name, QAPISchemaObjectType):
|
||||||
self._def_entity(QAPISchemaObjectType(name, info, None,
|
self._def_entity(QAPISchemaObjectType(name, info, None,
|
||||||
@ -1221,7 +1273,8 @@ class QAPISchema(object):
|
|||||||
name = expr['enum']
|
name = expr['enum']
|
||||||
data = expr['data']
|
data = expr['data']
|
||||||
prefix = expr.get('prefix')
|
prefix = expr.get('prefix')
|
||||||
self._def_entity(QAPISchemaEnumType(name, info, data, prefix))
|
self._def_entity(QAPISchemaEnumType(
|
||||||
|
name, info, self._make_enum_members(data), prefix))
|
||||||
|
|
||||||
def _make_member(self, name, typ, info):
|
def _make_member(self, name, typ, info):
|
||||||
optional = False
|
optional = False
|
||||||
@ -1256,11 +1309,6 @@ class QAPISchema(object):
|
|||||||
typ, info, 'wrapper', [self._make_member('data', typ, info)])
|
typ, info, 'wrapper', [self._make_member('data', typ, info)])
|
||||||
return QAPISchemaObjectTypeVariant(case, typ)
|
return QAPISchemaObjectTypeVariant(case, typ)
|
||||||
|
|
||||||
def _make_implicit_tag(self, type_name, info, variants):
|
|
||||||
typ = self._make_implicit_enum_type(type_name, info,
|
|
||||||
[v.name for v in variants])
|
|
||||||
return QAPISchemaObjectTypeMember('type', typ, False)
|
|
||||||
|
|
||||||
def _def_union_type(self, expr, info):
|
def _def_union_type(self, expr, info):
|
||||||
name = expr['union']
|
name = expr['union']
|
||||||
data = expr['data']
|
data = expr['data']
|
||||||
@ -1270,13 +1318,16 @@ class QAPISchema(object):
|
|||||||
if tag_name:
|
if tag_name:
|
||||||
variants = [self._make_variant(key, value)
|
variants = [self._make_variant(key, value)
|
||||||
for (key, value) in data.iteritems()]
|
for (key, value) in data.iteritems()]
|
||||||
|
members = []
|
||||||
else:
|
else:
|
||||||
variants = [self._make_simple_variant(key, value, info)
|
variants = [self._make_simple_variant(key, value, info)
|
||||||
for (key, value) in data.iteritems()]
|
for (key, value) in data.iteritems()]
|
||||||
tag_member = self._make_implicit_tag(name, info, variants)
|
typ = self._make_implicit_enum_type(name, info,
|
||||||
|
[v.name for v in variants])
|
||||||
|
tag_member = QAPISchemaObjectTypeMember('type', typ, False)
|
||||||
|
members = [tag_member]
|
||||||
self._def_entity(
|
self._def_entity(
|
||||||
QAPISchemaObjectType(name, info, base,
|
QAPISchemaObjectType(name, info, base, members,
|
||||||
self._make_members(OrderedDict(), info),
|
|
||||||
QAPISchemaObjectTypeVariants(tag_name,
|
QAPISchemaObjectTypeVariants(tag_name,
|
||||||
tag_member,
|
tag_member,
|
||||||
variants)))
|
variants)))
|
||||||
@ -1286,7 +1337,7 @@ class QAPISchema(object):
|
|||||||
data = expr['data']
|
data = expr['data']
|
||||||
variants = [self._make_variant(key, value)
|
variants = [self._make_variant(key, value)
|
||||||
for (key, value) in data.iteritems()]
|
for (key, value) in data.iteritems()]
|
||||||
tag_member = self._make_implicit_tag(name, info, variants)
|
tag_member = QAPISchemaObjectTypeMember('type', 'QType', False)
|
||||||
self._def_entity(
|
self._def_entity(
|
||||||
QAPISchemaAlternateType(name, info,
|
QAPISchemaAlternateType(name, info,
|
||||||
QAPISchemaObjectTypeVariants(None,
|
QAPISchemaObjectTypeVariants(None,
|
||||||
@ -1390,7 +1441,7 @@ def camel_to_upper(value):
|
|||||||
def c_enum_const(type_name, const_name, prefix=None):
|
def c_enum_const(type_name, const_name, prefix=None):
|
||||||
if prefix is not None:
|
if prefix is not None:
|
||||||
type_name = prefix
|
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('.-', '__')
|
c_name_trans = string.maketrans('.-', '__')
|
||||||
|
|
||||||
@ -1432,10 +1483,11 @@ def c_name(name, protect=True):
|
|||||||
'not_eq', 'or', 'or_eq', 'xor', 'xor_eq'])
|
'not_eq', 'or', 'or_eq', 'xor', 'xor_eq'])
|
||||||
# namespace pollution:
|
# namespace pollution:
|
||||||
polluted_words = set(['unix', 'errno'])
|
polluted_words = set(['unix', 'errno'])
|
||||||
|
name = name.translate(c_name_trans)
|
||||||
if protect and (name in c89_words | c99_words | c11_words | gcc_words
|
if protect and (name in c89_words | c99_words | c11_words | gcc_words
|
||||||
| cpp_words | polluted_words):
|
| cpp_words | polluted_words):
|
||||||
return "q_" + name
|
return "q_" + name
|
||||||
return name.translate(c_name_trans)
|
return name
|
||||||
|
|
||||||
eatspace = '\033EATSPACE.'
|
eatspace = '\033EATSPACE.'
|
||||||
pointer_suffix = ' *' + eatspace
|
pointer_suffix = ' *' + eatspace
|
||||||
@ -1515,7 +1567,7 @@ const char *const %(c_name)s_lookup[] = {
|
|||||||
''',
|
''',
|
||||||
index=index, value=value)
|
index=index, value=value)
|
||||||
|
|
||||||
max_index = c_enum_const(name, 'MAX', prefix)
|
max_index = c_enum_const(name, '_MAX', prefix)
|
||||||
ret += mcgen('''
|
ret += mcgen('''
|
||||||
[%(max_index)s] = NULL,
|
[%(max_index)s] = NULL,
|
||||||
};
|
};
|
||||||
@ -1526,7 +1578,7 @@ const char *const %(c_name)s_lookup[] = {
|
|||||||
|
|
||||||
def gen_enum(name, values, prefix=None):
|
def gen_enum(name, values, prefix=None):
|
||||||
# append automatically generated _MAX value
|
# append automatically generated _MAX value
|
||||||
enum_values = values + ['MAX']
|
enum_values = values + ['_MAX']
|
||||||
|
|
||||||
ret = mcgen('''
|
ret = mcgen('''
|
||||||
|
|
||||||
@ -1594,15 +1646,10 @@ def gen_visit_fields(members, prefix='', need_cast=False, skiperr=False):
|
|||||||
for memb in members:
|
for memb in members:
|
||||||
if memb.optional:
|
if memb.optional:
|
||||||
ret += mcgen('''
|
ret += mcgen('''
|
||||||
visit_optional(v, &%(prefix)shas_%(c_name)s, "%(name)s", %(errp)s);
|
if (visit_optional(v, &%(prefix)shas_%(c_name)s, "%(name)s")) {
|
||||||
''',
|
''',
|
||||||
prefix=prefix, c_name=c_name(memb.name),
|
prefix=prefix, c_name=c_name(memb.name),
|
||||||
name=memb.name, errp=errparg)
|
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()
|
push_indent()
|
||||||
|
|
||||||
# Ugly: sometimes we need to cast away const
|
# Ugly: sometimes we need to cast away const
|
||||||
|
@ -246,6 +246,7 @@ qapi-schema += args-array-unknown.json
|
|||||||
qapi-schema += args-int.json
|
qapi-schema += args-int.json
|
||||||
qapi-schema += args-invalid.json
|
qapi-schema += args-invalid.json
|
||||||
qapi-schema += args-member-array-bad.json
|
qapi-schema += args-member-array-bad.json
|
||||||
|
qapi-schema += args-member-case.json
|
||||||
qapi-schema += args-member-unknown.json
|
qapi-schema += args-member-unknown.json
|
||||||
qapi-schema += args-name-clash.json
|
qapi-schema += args-name-clash.json
|
||||||
qapi-schema += args-union.json
|
qapi-schema += args-union.json
|
||||||
@ -256,6 +257,8 @@ qapi-schema += bad-ident.json
|
|||||||
qapi-schema += bad-type-bool.json
|
qapi-schema += bad-type-bool.json
|
||||||
qapi-schema += bad-type-dict.json
|
qapi-schema += bad-type-dict.json
|
||||||
qapi-schema += bad-type-int.json
|
qapi-schema += bad-type-int.json
|
||||||
|
qapi-schema += base-cycle-direct.json
|
||||||
|
qapi-schema += base-cycle-indirect.json
|
||||||
qapi-schema += command-int.json
|
qapi-schema += command-int.json
|
||||||
qapi-schema += comments.json
|
qapi-schema += comments.json
|
||||||
qapi-schema += double-data.json
|
qapi-schema += double-data.json
|
||||||
@ -267,23 +270,20 @@ qapi-schema += enum-bad-prefix.json
|
|||||||
qapi-schema += enum-clash-member.json
|
qapi-schema += enum-clash-member.json
|
||||||
qapi-schema += enum-dict-member.json
|
qapi-schema += enum-dict-member.json
|
||||||
qapi-schema += enum-int-member.json
|
qapi-schema += enum-int-member.json
|
||||||
qapi-schema += enum-max-member.json
|
qapi-schema += enum-member-case.json
|
||||||
qapi-schema += enum-missing-data.json
|
qapi-schema += enum-missing-data.json
|
||||||
qapi-schema += enum-wrong-data.json
|
qapi-schema += enum-wrong-data.json
|
||||||
qapi-schema += escape-outside-string.json
|
qapi-schema += escape-outside-string.json
|
||||||
qapi-schema += escape-too-big.json
|
qapi-schema += escape-too-big.json
|
||||||
qapi-schema += escape-too-short.json
|
qapi-schema += escape-too-short.json
|
||||||
qapi-schema += event-case.json
|
qapi-schema += event-case.json
|
||||||
qapi-schema += event-max.json
|
|
||||||
qapi-schema += event-nest-struct.json
|
qapi-schema += event-nest-struct.json
|
||||||
qapi-schema += flat-union-array-branch.json
|
qapi-schema += flat-union-array-branch.json
|
||||||
qapi-schema += flat-union-bad-base.json
|
qapi-schema += flat-union-bad-base.json
|
||||||
qapi-schema += flat-union-bad-discriminator.json
|
qapi-schema += flat-union-bad-discriminator.json
|
||||||
qapi-schema += flat-union-base-any.json
|
qapi-schema += flat-union-base-any.json
|
||||||
qapi-schema += flat-union-base-union.json
|
qapi-schema += flat-union-base-union.json
|
||||||
qapi-schema += flat-union-clash-branch.json
|
|
||||||
qapi-schema += flat-union-clash-member.json
|
qapi-schema += flat-union-clash-member.json
|
||||||
qapi-schema += flat-union-clash-type.json
|
|
||||||
qapi-schema += flat-union-empty.json
|
qapi-schema += flat-union-empty.json
|
||||||
qapi-schema += flat-union-inline.json
|
qapi-schema += flat-union-inline.json
|
||||||
qapi-schema += flat-union-int-branch.json
|
qapi-schema += flat-union-int-branch.json
|
||||||
@ -320,9 +320,11 @@ qapi-schema += redefined-command.json
|
|||||||
qapi-schema += redefined-event.json
|
qapi-schema += redefined-event.json
|
||||||
qapi-schema += redefined-type.json
|
qapi-schema += redefined-type.json
|
||||||
qapi-schema += reserved-command-q.json
|
qapi-schema += reserved-command-q.json
|
||||||
|
qapi-schema += reserved-enum-q.json
|
||||||
qapi-schema += reserved-member-has.json
|
qapi-schema += reserved-member-has.json
|
||||||
qapi-schema += reserved-member-q.json
|
qapi-schema += reserved-member-q.json
|
||||||
qapi-schema += reserved-member-u.json
|
qapi-schema += reserved-member-u.json
|
||||||
|
qapi-schema += reserved-member-underscore.json
|
||||||
qapi-schema += reserved-type-kind.json
|
qapi-schema += reserved-type-kind.json
|
||||||
qapi-schema += reserved-type-list.json
|
qapi-schema += reserved-type-list.json
|
||||||
qapi-schema += returns-alternate.json
|
qapi-schema += returns-alternate.json
|
||||||
@ -341,14 +343,12 @@ qapi-schema += unclosed-list.json
|
|||||||
qapi-schema += unclosed-object.json
|
qapi-schema += unclosed-object.json
|
||||||
qapi-schema += unclosed-string.json
|
qapi-schema += unclosed-string.json
|
||||||
qapi-schema += unicode-str.json
|
qapi-schema += unicode-str.json
|
||||||
qapi-schema += union-bad-branch.json
|
|
||||||
qapi-schema += union-base-no-discriminator.json
|
qapi-schema += union-base-no-discriminator.json
|
||||||
|
qapi-schema += union-branch-case.json
|
||||||
qapi-schema += union-clash-branches.json
|
qapi-schema += union-clash-branches.json
|
||||||
qapi-schema += union-clash-data.json
|
qapi-schema += union-clash-data.json
|
||||||
qapi-schema += union-clash-type.json
|
|
||||||
qapi-schema += union-empty.json
|
qapi-schema += union-empty.json
|
||||||
qapi-schema += union-invalid-base.json
|
qapi-schema += union-invalid-base.json
|
||||||
qapi-schema += union-max.json
|
|
||||||
qapi-schema += union-optional-branch.json
|
qapi-schema += union-optional-branch.json
|
||||||
qapi-schema += union-unknown.json
|
qapi-schema += union-unknown.json
|
||||||
qapi-schema += unknown-escape.json
|
qapi-schema += unknown-escape.json
|
||||||
|
@ -1 +1 @@
|
|||||||
tests/qapi-schema/alternate-clash.json:7: Alternate 'Alt1' member 'a_b' clashes with 'a-b'
|
tests/qapi-schema/alternate-clash.json:7: 'a_b' (branch of Alt1) collides with 'a-b' (branch of Alt1)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
object :empty
|
object :empty
|
||||||
alternate Alt
|
alternate Alt
|
||||||
case i: int
|
case i: int
|
||||||
enum AltKind ['i']
|
enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
|
||||||
|
prefix QTYPE
|
||||||
|
1
tests/qapi-schema/args-member-case.err
Normal file
1
tests/qapi-schema/args-member-case.err
Normal file
@ -0,0 +1 @@
|
|||||||
|
tests/qapi-schema/args-member-case.json:2: 'Arg' (parameter of no-way-this-will-get-whitelisted) should not use uppercase
|
2
tests/qapi-schema/args-member-case.json
Normal file
2
tests/qapi-schema/args-member-case.json
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# Member names should be 'lower-case' unless the struct/command is whitelisted
|
||||||
|
{ 'command': 'no-way-this-will-get-whitelisted', 'data': { 'Arg': 'int' } }
|
@ -0,0 +1 @@
|
|||||||
|
tests/qapi-schema/args-name-clash.json:4: 'a_b' (parameter of oops) collides with 'a-b' (parameter of oops)
|
@ -1 +1 @@
|
|||||||
0
|
1
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
# C member name collision
|
# C member name collision
|
||||||
# FIXME - This parses, but fails to compile, because the C struct is given
|
# Reject members that clash when mapped to C names (we would have two 'a_b'
|
||||||
# two 'a_b' members. Either reject this at parse time, or munge the C names
|
# members).
|
||||||
# to avoid the collision.
|
|
||||||
{ 'command': 'oops', 'data': { 'a-b': 'str', 'a_b': 'str' } }
|
{ 'command': 'oops', 'data': { 'a-b': 'str', 'a_b': 'str' } }
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
object :empty
|
|
||||||
object :obj-oops-arg
|
|
||||||
member a-b: str optional=False
|
|
||||||
member a_b: str optional=False
|
|
||||||
command oops :obj-oops-arg -> None
|
|
||||||
gen=True success_response=True
|
|
1
tests/qapi-schema/base-cycle-direct.err
Normal file
1
tests/qapi-schema/base-cycle-direct.err
Normal file
@ -0,0 +1 @@
|
|||||||
|
tests/qapi-schema/base-cycle-direct.json:2: Object Loopy contains itself
|
2
tests/qapi-schema/base-cycle-direct.json
Normal file
2
tests/qapi-schema/base-cycle-direct.json
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# we reject a loop in base classes
|
||||||
|
{ 'struct': 'Loopy', 'base': 'Loopy', 'data': {} }
|
1
tests/qapi-schema/base-cycle-indirect.err
Normal file
1
tests/qapi-schema/base-cycle-indirect.err
Normal file
@ -0,0 +1 @@
|
|||||||
|
tests/qapi-schema/base-cycle-indirect.json:2: Object Base1 contains itself
|
3
tests/qapi-schema/base-cycle-indirect.json
Normal file
3
tests/qapi-schema/base-cycle-indirect.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# we reject a loop in base classes
|
||||||
|
{ 'struct': 'Base1', 'base': 'Base2', 'data': {} }
|
||||||
|
{ 'struct': 'Base2', 'base': 'Base1', 'data': {} }
|
@ -1,2 +1,4 @@
|
|||||||
object :empty
|
object :empty
|
||||||
|
enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
|
||||||
|
prefix QTYPE
|
||||||
enum Status ['good', 'bad', 'ugly']
|
enum Status ['good', 'bad', 'ugly']
|
||||||
|
@ -1 +1,3 @@
|
|||||||
object :empty
|
object :empty
|
||||||
|
enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
|
||||||
|
prefix QTYPE
|
||||||
|
@ -1 +1 @@
|
|||||||
tests/qapi-schema/enum-clash-member.json:2: Enum 'MyEnum' member 'ONE' clashes with 'one'
|
tests/qapi-schema/enum-clash-member.json:2: 'one_two' (member of MyEnum) collides with 'one-two' (member of MyEnum)
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
# we reject enums where members will clash when mapped to C enum
|
# we reject enums where members will clash when mapped to C enum
|
||||||
{ 'enum': 'MyEnum', 'data': [ 'one', 'ONE' ] }
|
{ 'enum': 'MyEnum', 'data': [ 'one-two', 'one_two' ] }
|
||||||
|
@ -1 +0,0 @@
|
|||||||
tests/qapi-schema/enum-max-member.json:3: Enum 'MyEnum' member 'max' clashes with '(automatic)'
|
|
@ -1,3 +0,0 @@
|
|||||||
# we reject user-supplied 'max' for clashing with implicit enum end
|
|
||||||
# TODO: should we instead munge the implicit value to avoid the clash?
|
|
||||||
{ 'enum': 'MyEnum', 'data': [ 'max' ] }
|
|
1
tests/qapi-schema/enum-member-case.err
Normal file
1
tests/qapi-schema/enum-member-case.err
Normal file
@ -0,0 +1 @@
|
|||||||
|
tests/qapi-schema/enum-member-case.json:3: 'Value' (member of NoWayThisWillGetWhitelisted) should not use uppercase
|
3
tests/qapi-schema/enum-member-case.json
Normal file
3
tests/qapi-schema/enum-member-case.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Member names should be 'lower-case' unless the enum is whitelisted
|
||||||
|
{ 'enum': 'UuidInfo', 'data': [ 'Value' ] } # UuidInfo is whitelisted
|
||||||
|
{ 'enum': 'NoWayThisWillGetWhitelisted', 'data': [ 'Value' ] }
|
@ -1,2 +1,4 @@
|
|||||||
object :empty
|
object :empty
|
||||||
|
enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
|
||||||
|
prefix QTYPE
|
||||||
event oops None
|
event oops None
|
||||||
|
@ -1 +0,0 @@
|
|||||||
tests/qapi-schema/event-max.json:2: Event name 'MAX' cannot be created
|
|
@ -1,2 +0,0 @@
|
|||||||
# an event named 'MAX' would conflict with implicit C enum
|
|
||||||
{ 'event': 'MAX' }
|
|
@ -1 +0,0 @@
|
|||||||
0
|
|
@ -1,18 +0,0 @@
|
|||||||
# Flat union branch name collision
|
|
||||||
# FIXME: this parses, but then fails to compile due to a duplicate 'c_d'
|
|
||||||
# (one from the base member, the other from the branch name). We should
|
|
||||||
# either reject the collision at parse time, or munge the generated branch
|
|
||||||
# name to allow this to compile.
|
|
||||||
{ 'enum': 'TestEnum',
|
|
||||||
'data': [ 'base', 'c-d' ] }
|
|
||||||
{ 'struct': 'Base',
|
|
||||||
'data': { 'enum1': 'TestEnum', '*c_d': 'str' } }
|
|
||||||
{ 'struct': 'Branch1',
|
|
||||||
'data': { 'string': 'str' } }
|
|
||||||
{ 'struct': 'Branch2',
|
|
||||||
'data': { 'value': 'int' } }
|
|
||||||
{ 'union': 'TestUnion',
|
|
||||||
'base': 'Base',
|
|
||||||
'discriminator': 'enum1',
|
|
||||||
'data': { 'base': 'Branch1',
|
|
||||||
'c-d': 'Branch2' } }
|
|
@ -1,14 +0,0 @@
|
|||||||
object :empty
|
|
||||||
object Base
|
|
||||||
member enum1: TestEnum optional=False
|
|
||||||
member c_d: str optional=True
|
|
||||||
object Branch1
|
|
||||||
member string: str optional=False
|
|
||||||
object Branch2
|
|
||||||
member value: int optional=False
|
|
||||||
enum TestEnum ['base', 'c-d']
|
|
||||||
object TestUnion
|
|
||||||
base Base
|
|
||||||
tag enum1
|
|
||||||
case base: Branch1
|
|
||||||
case c-d: Branch2
|
|
@ -1 +1 @@
|
|||||||
tests/qapi-schema/flat-union-clash-member.json:11: Member name 'name' of branch 'value1' clashes with base 'Base'
|
tests/qapi-schema/flat-union-clash-member.json:11: 'name' (member of Branch1) collides with 'name' (member of Base)
|
||||||
|
@ -1 +0,0 @@
|
|||||||
tests/qapi-schema/flat-union-clash-type.json:11: Discriminator name 'type' collides with enum value in 'TestEnum'
|
|
@ -1,14 +0,0 @@
|
|||||||
# Flat union branch 'type'
|
|
||||||
# Reject this, because we would have a clash in generated C, between the
|
|
||||||
# outer tag 'type' and the branch name 'type' within the union.
|
|
||||||
# TODO: We could munge the generated C branch name to let it compile.
|
|
||||||
{ 'enum': 'TestEnum',
|
|
||||||
'data': [ 'type' ] }
|
|
||||||
{ 'struct': 'Base',
|
|
||||||
'data': { 'type': 'TestEnum' } }
|
|
||||||
{ 'struct': 'Branch1',
|
|
||||||
'data': { 'string': 'str' } }
|
|
||||||
{ 'union': 'TestUnion',
|
|
||||||
'base': 'Base',
|
|
||||||
'discriminator': 'type',
|
|
||||||
'data': { 'type': 'Branch1' } }
|
|
@ -2,6 +2,8 @@ object :empty
|
|||||||
object Base
|
object Base
|
||||||
member type: Empty optional=False
|
member type: Empty optional=False
|
||||||
enum Empty []
|
enum Empty []
|
||||||
|
enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
|
||||||
|
prefix QTYPE
|
||||||
object Union
|
object Union
|
||||||
base Base
|
base Base
|
||||||
tag type
|
tag type
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
object :empty
|
object :empty
|
||||||
object :obj-fooA-arg
|
object :obj-fooA-arg
|
||||||
member bar1: str optional=False
|
member bar1: str optional=False
|
||||||
|
enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
|
||||||
|
prefix QTYPE
|
||||||
command fooA :obj-fooA-arg -> None
|
command fooA :obj-fooA-arg -> None
|
||||||
gen=True success_response=True
|
gen=True success_response=True
|
||||||
|
@ -1,2 +1,4 @@
|
|||||||
object :empty
|
object :empty
|
||||||
|
enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
|
||||||
|
prefix QTYPE
|
||||||
enum Status ['good', 'bad', 'ugly']
|
enum Status ['good', 'bad', 'ugly']
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user