diff options
108 files changed, 1157 insertions, 937 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 120788d8fb..05e6e963ba 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1411,8 +1411,7 @@ F: include/qapi/qmp/ X: include/qapi/qmp/dispatch.h F: scripts/coccinelle/qobject.cocci F: tests/check-qdict.c -F: tests/check-qfloat.c -F: tests/check-qint.c +F: tests/check-qnum.c F: tests/check-qjson.c F: tests/check-qlist.c F: tests/check-qstring.c diff --git a/backends/cryptodev.c b/backends/cryptodev.c index 832f056266..1764c179fe 100644 --- a/backends/cryptodev.c +++ b/backends/cryptodev.c @@ -222,7 +222,7 @@ cryptodev_backend_can_be_deleted(UserCreatable *uc, Error **errp) static void cryptodev_backend_instance_init(Object *obj) { - object_property_add(obj, "queues", "int", + object_property_add(obj, "queues", "uint32", cryptodev_backend_get_queues, cryptodev_backend_set_queues, NULL, NULL, NULL); diff --git a/block/blkdebug.c b/block/blkdebug.c index a5196e889d..0618fc71c6 100644 --- a/block/blkdebug.c +++ b/block/blkdebug.c @@ -31,7 +31,6 @@ #include "qemu/module.h" #include "qapi/qmp/qbool.h" #include "qapi/qmp/qdict.h" -#include "qapi/qmp/qint.h" #include "qapi/qmp/qstring.h" #include "sysemu/qtest.h" diff --git a/block/nbd.c b/block/nbd.c index 975faab2c5..e946ea944d 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -37,7 +37,6 @@ #include "qapi/qobject-output-visitor.h" #include "qapi/qmp/qdict.h" #include "qapi/qmp/qjson.h" -#include "qapi/qmp/qint.h" #include "qapi/qmp/qstring.h" #include "qemu/cutils.h" diff --git a/block/nfs.c b/block/nfs.c index 18c87d2f25..6b8b5b653d 100644 --- a/block/nfs.c +++ b/block/nfs.c @@ -36,7 +36,6 @@ #include "qemu/cutils.h" #include "sysemu/sysemu.h" #include "qapi/qmp/qdict.h" -#include "qapi/qmp/qint.h" #include "qapi/qmp/qstring.h" #include "qapi-visit.h" #include "qapi/qobject-input-visitor.h" diff --git a/block/qapi.c b/block/qapi.c index 14b60ae66c..0a41d59bf3 100644 --- a/block/qapi.c +++ b/block/qapi.c @@ -595,9 +595,11 @@ static void dump_qobject(fprintf_function func_fprintf, void *f, int comp_indent, QObject *obj) { switch (qobject_type(obj)) { - case QTYPE_QINT: { - QInt *value = qobject_to_qint(obj); - func_fprintf(f, "%" PRId64, qint_get_int(value)); + case QTYPE_QNUM: { + QNum *value = qobject_to_qnum(obj); + char *tmp = qnum_to_string(value); + func_fprintf(f, "%s", tmp); + g_free(tmp); break; } case QTYPE_QSTRING: { @@ -615,11 +617,6 @@ static void dump_qobject(fprintf_function func_fprintf, void *f, dump_qlist(func_fprintf, f, comp_indent, value); break; } - case QTYPE_QFLOAT: { - QFloat *value = qobject_to_qfloat(obj); - func_fprintf(f, "%g", qfloat_get_double(value)); - break; - } case QTYPE_QBOOL: { QBool *value = qobject_to_qbool(obj); func_fprintf(f, "%s", qbool_get_bool(value) ? "true" : "false"); diff --git a/block/quorum.c b/block/quorum.c index 1b2a8c3937..55ba916655 100644 --- a/block/quorum.c +++ b/block/quorum.c @@ -19,7 +19,6 @@ #include "qapi/qmp/qbool.h" #include "qapi/qmp/qdict.h" #include "qapi/qmp/qerror.h" -#include "qapi/qmp/qint.h" #include "qapi/qmp/qjson.h" #include "qapi/qmp/qlist.h" #include "qapi/qmp/qstring.h" diff --git a/block/sheepdog.c b/block/sheepdog.c index 5ebf5d9fbb..c9236679c6 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -16,7 +16,6 @@ #include "qapi-visit.h" #include "qapi/error.h" #include "qapi/qmp/qdict.h" -#include "qapi/qmp/qint.h" #include "qapi/qobject-input-visitor.h" #include "qemu/uri.h" #include "qemu/error-report.h" diff --git a/block/ssh.c b/block/ssh.c index 11203fc5a2..bac3453c3e 100644 --- a/block/ssh.c +++ b/block/ssh.c @@ -34,7 +34,6 @@ #include "qemu/sockets.h" #include "qemu/uri.h" #include "qapi-visit.h" -#include "qapi/qmp/qint.h" #include "qapi/qmp/qstring.h" #include "qapi/qobject-input-visitor.h" #include "qapi/qobject-output-visitor.h" diff --git a/block/vvfat.c b/block/vvfat.c index 426ca70e35..8ab647c0c6 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -29,7 +29,6 @@ #include "qemu/module.h" #include "qemu/bswap.h" #include "migration/blocker.h" -#include "qapi/qmp/qint.h" #include "qapi/qmp/qbool.h" #include "qapi/qmp/qstring.h" #include "qemu/cutils.h" diff --git a/blockdev.c b/blockdev.c index 39d6b9712b..f92dcf24bf 100644 --- a/blockdev.c +++ b/blockdev.c @@ -334,8 +334,9 @@ static bool parse_stats_intervals(BlockAcctStats *stats, QList *intervals, break; } - case QTYPE_QINT: { - int64_t length = qint_get_int(qobject_to_qint(entry->value)); + case QTYPE_QNUM: { + int64_t length = qnum_get_int(qobject_to_qnum(entry->value)); + if (length > 0 && length <= UINT_MAX) { block_acct_add_interval(stats, (unsigned) length); } else { diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c index 210073d283..cda2c9dd06 100644 --- a/hw/acpi/memory_hotplug.c +++ b/hw/acpi/memory_hotplug.c @@ -83,23 +83,25 @@ static uint64_t acpi_memory_hotplug_read(void *opaque, hwaddr addr, o = OBJECT(mdev->dimm); switch (addr) { case 0x0: /* Lo part of phys address where DIMM is mapped */ - val = o ? object_property_get_int(o, PC_DIMM_ADDR_PROP, NULL) : 0; + val = o ? object_property_get_uint(o, PC_DIMM_ADDR_PROP, NULL) : 0; trace_mhp_acpi_read_addr_lo(mem_st->selector, val); break; case 0x4: /* Hi part of phys address where DIMM is mapped */ - val = o ? object_property_get_int(o, PC_DIMM_ADDR_PROP, NULL) >> 32 : 0; + val = + o ? object_property_get_uint(o, PC_DIMM_ADDR_PROP, NULL) >> 32 : 0; trace_mhp_acpi_read_addr_hi(mem_st->selector, val); break; case 0x8: /* Lo part of DIMM size */ - val = o ? object_property_get_int(o, PC_DIMM_SIZE_PROP, NULL) : 0; + val = o ? object_property_get_uint(o, PC_DIMM_SIZE_PROP, NULL) : 0; trace_mhp_acpi_read_size_lo(mem_st->selector, val); break; case 0xc: /* Hi part of DIMM size */ - val = o ? object_property_get_int(o, PC_DIMM_SIZE_PROP, NULL) >> 32 : 0; + val = + o ? object_property_get_uint(o, PC_DIMM_SIZE_PROP, NULL) >> 32 : 0; trace_mhp_acpi_read_size_hi(mem_st->selector, val); break; case 0x10: /* node proximity for _PXM method */ - val = o ? object_property_get_int(o, PC_DIMM_NODE_PROP, NULL) : 0; + val = o ? object_property_get_uint(o, PC_DIMM_NODE_PROP, NULL) : 0; trace_mhp_acpi_read_pxm(mem_st->selector, val); break; case 0x14: /* pack and return is_* fields */ diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c index b5734f5897..6ceea196e7 100644 --- a/hw/acpi/nvdimm.c +++ b/hw/acpi/nvdimm.c @@ -236,14 +236,14 @@ static void nvdimm_build_structure_spa(GArray *structures, DeviceState *dev) { NvdimmNfitSpa *nfit_spa; - uint64_t addr = object_property_get_int(OBJECT(dev), PC_DIMM_ADDR_PROP, - NULL); - uint64_t size = object_property_get_int(OBJECT(dev), PC_DIMM_SIZE_PROP, - NULL); - uint32_t node = object_property_get_int(OBJECT(dev), PC_DIMM_NODE_PROP, - NULL); + uint64_t addr = object_property_get_uint(OBJECT(dev), PC_DIMM_ADDR_PROP, + NULL); + uint64_t size = object_property_get_uint(OBJECT(dev), PC_DIMM_SIZE_PROP, + NULL); + uint32_t node = object_property_get_uint(OBJECT(dev), PC_DIMM_NODE_PROP, + NULL); int slot = object_property_get_int(OBJECT(dev), PC_DIMM_SLOT_PROP, - NULL); + NULL); nfit_spa = acpi_data_push(structures, sizeof(*nfit_spa)); @@ -284,8 +284,8 @@ static void nvdimm_build_structure_memdev(GArray *structures, DeviceState *dev) { NvdimmNfitMemDev *nfit_memdev; - uint64_t size = object_property_get_int(OBJECT(dev), PC_DIMM_SIZE_PROP, - NULL); + uint64_t size = object_property_get_uint(OBJECT(dev), PC_DIMM_SIZE_PROP, + NULL); int slot = object_property_get_int(OBJECT(dev), PC_DIMM_SLOT_PROP, NULL); uint32_t handle = nvdimm_slot_to_handle(slot); diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c index 2b0f3e1bfb..c420a388ea 100644 --- a/hw/acpi/pcihp.c +++ b/hw/acpi/pcihp.c @@ -37,7 +37,6 @@ #include "hw/pci/pci_bus.h" #include "qapi/error.h" #include "qom/qom-qobject.h" -#include "qapi/qmp/qint.h" //#define DEBUG @@ -63,10 +62,10 @@ typedef struct AcpiPciHpFind { static int acpi_pcihp_get_bsel(PCIBus *bus) { Error *local_err = NULL; - int64_t bsel = object_property_get_int(OBJECT(bus), ACPI_PCIHP_PROP_BSEL, - &local_err); + uint64_t bsel = object_property_get_uint(OBJECT(bus), ACPI_PCIHP_PROP_BSEL, + &local_err); - if (local_err || bsel < 0 || bsel >= ACPI_PCIHP_MAX_HOTPLUG_BUS) { + if (local_err || bsel >= ACPI_PCIHP_MAX_HOTPLUG_BUS) { if (local_err) { error_free(local_err); } diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c index 155eeb242b..db3f6d20c6 100644 --- a/hw/arm/aspeed.c +++ b/hw/arm/aspeed.c @@ -180,8 +180,8 @@ static void aspeed_board_init(MachineState *machine, sc = ASPEED_SOC_GET_CLASS(&bmc->soc); - object_property_set_int(OBJECT(&bmc->soc), ram_size, "ram-size", - &error_abort); + object_property_set_uint(OBJECT(&bmc->soc), ram_size, "ram-size", + &error_abort); object_property_set_int(OBJECT(&bmc->soc), cfg->hw_strap1, "hw-strap1", &error_abort); object_property_set_int(OBJECT(&bmc->soc), cfg->num_cs, "num-cs", @@ -193,8 +193,8 @@ static void aspeed_board_init(MachineState *machine, * Allocate RAM after the memory controller has checked the size * was valid. If not, a default value is used. */ - ram_size = object_property_get_int(OBJECT(&bmc->soc), "ram-size", - &error_abort); + ram_size = object_property_get_uint(OBJECT(&bmc->soc), "ram-size", + &error_abort); memory_region_allocate_system_memory(&bmc->ram, NULL, "ram", ram_size); memory_region_add_subregion(get_system_memory(), sc->info->sdram_base, diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c index 502f04c02a..12e0dd11af 100644 --- a/hw/arm/bcm2835_peripherals.c +++ b/hw/arm/bcm2835_peripherals.c @@ -125,7 +125,7 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp) Object *obj; MemoryRegion *ram; Error *err = NULL; - uint32_t ram_size, vcram_size; + uint64_t ram_size, vcram_size; int n; obj = object_property_get_link(OBJECT(dev), "ram", &err); @@ -207,15 +207,14 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp) INTERRUPT_ARM_MAILBOX)); /* Framebuffer */ - vcram_size = (uint32_t)object_property_get_int(OBJECT(s), "vcram-size", - &err); + vcram_size = object_property_get_uint(OBJECT(s), "vcram-size", &err); if (err) { error_propagate(errp, err); return; } - object_property_set_int(OBJECT(&s->fb), ram_size - vcram_size, - "vcram-base", &err); + object_property_set_uint(OBJECT(&s->fb), ram_size - vcram_size, + "vcram-base", &err); if (err) { error_propagate(errp, err); return; diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index 2b295f14c4..32cdc98c6d 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -153,8 +153,8 @@ static void raspi2_init(MachineState *machine) qdev_prop_set_drive(carddev, "drive", blk, &error_fatal); object_property_set_bool(OBJECT(carddev), true, "realized", &error_fatal); - vcram_size = object_property_get_int(OBJECT(&s->soc), "vcram-size", - &error_abort); + vcram_size = object_property_get_uint(OBJECT(&s->soc), "vcram-size", + &error_abort); setup_boot(machine, 2, machine->ram_size - vcram_size); } diff --git a/hw/block/fdc.c b/hw/block/fdc.c index 2e629b398b..28f6b6ee35 100644 --- a/hw/block/fdc.c +++ b/hw/block/fdc.c @@ -511,7 +511,7 @@ typedef struct FloppyDrive { static Property floppy_drive_properties[] = { DEFINE_PROP_UINT32("unit", FloppyDrive, unit, -1), DEFINE_BLOCK_PROPERTIES(FloppyDrive, conf), - DEFINE_PROP_DEFAULT("drive-type", FloppyDrive, type, + DEFINE_PROP_SIGNED("drive-type", FloppyDrive, type, FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type, FloppyDriveType), DEFINE_PROP_END_OF_LIST(), @@ -2805,13 +2805,13 @@ static Property isa_fdc_properties[] = { DEFINE_PROP_DRIVE("driveB", FDCtrlISABus, state.qdev_for_drives[1].blk), DEFINE_PROP_BIT("check_media_rate", FDCtrlISABus, state.check_media_rate, 0, true), - DEFINE_PROP_DEFAULT("fdtypeA", FDCtrlISABus, state.qdev_for_drives[0].type, + DEFINE_PROP_SIGNED("fdtypeA", FDCtrlISABus, state.qdev_for_drives[0].type, FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type, FloppyDriveType), - DEFINE_PROP_DEFAULT("fdtypeB", FDCtrlISABus, state.qdev_for_drives[1].type, + DEFINE_PROP_SIGNED("fdtypeB", FDCtrlISABus, state.qdev_for_drives[1].type, FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type, FloppyDriveType), - DEFINE_PROP_DEFAULT("fallback", FDCtrlISABus, state.fallback, + DEFINE_PROP_SIGNED("fallback", FDCtrlISABus, state.fallback, FLOPPY_DRIVE_TYPE_288, qdev_prop_fdc_drive_type, FloppyDriveType), DEFINE_PROP_END_OF_LIST(), @@ -2862,13 +2862,13 @@ static const VMStateDescription vmstate_sysbus_fdc ={ static Property sysbus_fdc_properties[] = { DEFINE_PROP_DRIVE("driveA", FDCtrlSysBus, state.qdev_for_drives[0].blk), DEFINE_PROP_DRIVE("driveB", FDCtrlSysBus, state.qdev_for_drives[1].blk), - DEFINE_PROP_DEFAULT("fdtypeA", FDCtrlSysBus, state.qdev_for_drives[0].type, + DEFINE_PROP_SIGNED("fdtypeA", FDCtrlSysBus, state.qdev_for_drives[0].type, FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type, FloppyDriveType), - DEFINE_PROP_DEFAULT("fdtypeB", FDCtrlSysBus, state.qdev_for_drives[1].type, + DEFINE_PROP_SIGNED("fdtypeB", FDCtrlSysBus, state.qdev_for_drives[1].type, FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type, FloppyDriveType), - DEFINE_PROP_DEFAULT("fallback", FDCtrlISABus, state.fallback, + DEFINE_PROP_SIGNED("fallback", FDCtrlISABus, state.fallback, FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type, FloppyDriveType), DEFINE_PROP_END_OF_LIST(), @@ -2891,10 +2891,10 @@ static const TypeInfo sysbus_fdc_info = { static Property sun4m_fdc_properties[] = { DEFINE_PROP_DRIVE("drive", FDCtrlSysBus, state.qdev_for_drives[0].blk), - DEFINE_PROP_DEFAULT("fdtype", FDCtrlSysBus, state.qdev_for_drives[0].type, + DEFINE_PROP_SIGNED("fdtype", FDCtrlSysBus, state.qdev_for_drives[0].type, FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type, FloppyDriveType), - DEFINE_PROP_DEFAULT("fallback", FDCtrlISABus, state.fallback, + DEFINE_PROP_SIGNED("fallback", FDCtrlISABus, state.fallback, FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type, FloppyDriveType), DEFINE_PROP_END_OF_LIST(), diff --git a/hw/core/platform-bus.c b/hw/core/platform-bus.c index 329ac670c0..33d32fbf22 100644 --- a/hw/core/platform-bus.c +++ b/hw/core/platform-bus.c @@ -71,7 +71,7 @@ hwaddr platform_bus_get_mmio_addr(PlatformBusDevice *pbus, SysBusDevice *sbdev, return -1; } - return object_property_get_int(OBJECT(sbdev_mr), "addr", NULL); + return object_property_get_uint(OBJECT(sbdev_mr), "addr", NULL); } static void platform_bus_count_irqs(SysBusDevice *sbdev, void *opaque) diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c index 9f1a497322..68cd65345c 100644 --- a/hw/core/qdev-properties.c +++ b/hw/core/qdev-properties.c @@ -69,6 +69,12 @@ static void set_enum(Object *obj, Visitor *v, const char *name, void *opaque, visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp); } +static void set_default_value_enum(Object *obj, const Property *prop) +{ + object_property_set_str(obj, prop->info->enum_table[prop->defval.i], + prop->name, &error_abort); +} + /* Bit */ static uint32_t qdev_get_prop_mask(Property *prop) @@ -120,11 +126,17 @@ static void prop_set_bit(Object *obj, Visitor *v, const char *name, bit_prop_set(dev, prop, value); } +static void set_default_value_bool(Object *obj, const Property *prop) +{ + object_property_set_bool(obj, prop->defval.u, prop->name, &error_abort); +} + PropertyInfo qdev_prop_bit = { .name = "bool", .description = "on/off", .get = prop_get_bit, .set = prop_set_bit, + .set_default_value = set_default_value_bool, }; /* Bit64 */ @@ -183,6 +195,7 @@ PropertyInfo qdev_prop_bit64 = { .description = "on/off", .get = prop_get_bit64, .set = prop_set_bit64, + .set_default_value = set_default_value_bool, }; /* --- bool --- */ @@ -216,6 +229,7 @@ PropertyInfo qdev_prop_bool = { .name = "bool", .get = get_bool, .set = set_bool, + .set_default_value = set_default_value_bool, }; /* --- 8bit integer --- */ @@ -245,10 +259,21 @@ static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque, visit_type_uint8(v, name, ptr, errp); } +static void set_default_value_int(Object *obj, const Property *prop) +{ + object_property_set_int(obj, prop->defval.i, prop->name, &error_abort); +} + +static void set_default_value_uint(Object *obj, const Property *prop) +{ + object_property_set_uint(obj, prop->defval.u, prop->name, &error_abort); +} + PropertyInfo qdev_prop_uint8 = { .name = "uint8", .get = get_uint8, .set = set_uint8, + .set_default_value = set_default_value_uint, }; /* --- 16bit integer --- */ @@ -282,6 +307,7 @@ PropertyInfo qdev_prop_uint16 = { .name = "uint16", .get = get_uint16, .set = set_uint16, + .set_default_value = set_default_value_uint, }; /* --- 32bit integer --- */ @@ -340,12 +366,14 @@ PropertyInfo qdev_prop_uint32 = { .name = "uint32", .get = get_uint32, .set = set_uint32, + .set_default_value = set_default_value_uint, }; PropertyInfo qdev_prop_int32 = { .name = "int32", .get = get_int32, .set = set_int32, + .set_default_value = set_default_value_int, }; /* --- 64bit integer --- */ @@ -379,6 +407,7 @@ PropertyInfo qdev_prop_uint64 = { .name = "uint64", .get = get_uint64, .set = set_uint64, + .set_default_value = set_default_value_uint, }; /* --- string --- */ @@ -526,6 +555,7 @@ PropertyInfo qdev_prop_on_off_auto = { .enum_table = OnOffAuto_lookup, .get = get_enum, .set = set_enum, + .set_default_value = set_default_value_enum, }; /* --- lost tick policy --- */ @@ -537,6 +567,7 @@ PropertyInfo qdev_prop_losttickpolicy = { .enum_table = LostTickPolicy_lookup, .get = get_enum, .set = set_enum, + .set_default_value = set_default_value_enum, }; /* --- Block device error handling policy --- */ @@ -550,6 +581,7 @@ PropertyInfo qdev_prop_blockdev_on_error = { .enum_table = BlockdevOnError_lookup, .get = get_enum, .set = set_enum, + .set_default_value = set_default_value_enum, }; /* --- BIOS CHS translation */ @@ -563,6 +595,7 @@ PropertyInfo qdev_prop_bios_chs_trans = { .enum_table = BiosAtaTranslation_lookup, .get = get_enum, .set = set_enum, + .set_default_value = set_default_value_enum, }; /* --- FDC default drive types */ @@ -573,7 +606,8 @@ PropertyInfo qdev_prop_fdc_drive_type = { "144/288/120/none/auto", .enum_table = FloppyDriveType_lookup, .get = get_enum, - .set = set_enum + .set = set_enum, + .set_default_value = set_default_value_enum, }; /* --- pci address --- */ @@ -648,6 +682,7 @@ PropertyInfo qdev_prop_pci_devfn = { .print = print_pci_devfn, .get = get_int32, .set = set_pci_devfn, + .set_default_value = set_default_value_int, }; /* --- blocksize --- */ @@ -695,6 +730,7 @@ PropertyInfo qdev_prop_blocksize = { .description = "A power of two between 512 and 32768", .get = get_uint16, .set = set_blocksize, + .set_default_value = set_default_value_uint, }; /* --- pci host address --- */ @@ -917,6 +953,7 @@ PropertyInfo qdev_prop_arraylen = { .name = "uint32", .get = get_uint32, .set = set_prop_arraylen, + .set_default_value = set_default_value_uint, }; /* --- public helpers --- */ @@ -1153,4 +1190,5 @@ PropertyInfo qdev_prop_size = { .name = "size", .get = get_size, .set = set_size, + .set_default_value = set_default_value_uint, }; diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 0ce45a2019..849952a8d4 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -793,17 +793,8 @@ void qdev_property_add_static(DeviceState *dev, Property *prop, prop->info->description, &error_abort); - if (prop->qtype == QTYPE_NONE) { - return; - } - - if (prop->qtype == QTYPE_QBOOL) { - object_property_set_bool(obj, prop->defval, prop->name, &error_abort); - } else if (prop->info->enum_table) { - object_property_set_str(obj, prop->info->enum_table[prop->defval], - prop->name, &error_abort); - } else if (prop->qtype == QTYPE_QINT) { - object_property_set_int(obj, prop->defval, prop->name, &error_abort); + if (prop->info->set_default_value) { + prop->info->set_default_value(obj, prop); } } diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index ce74c84460..0b8bc62b99 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -57,7 +57,6 @@ #include "hw/acpi/aml-build.h" -#include "qapi/qmp/qint.h" #include "qom/qom-qobject.h" #include "hw/i386/amd_iommu.h" #include "hw/i386/intel_iommu.h" @@ -137,9 +136,9 @@ static void acpi_get_pm_info(AcpiPmInfo *pm) obj = piix; pm->cpu_hp_io_base = PIIX4_CPU_HOTPLUG_IO_BASE; pm->pcihp_io_base = - object_property_get_int(obj, ACPI_PCIHP_IO_BASE_PROP, NULL); + object_property_get_uint(obj, ACPI_PCIHP_IO_BASE_PROP, NULL); pm->pcihp_io_len = - object_property_get_int(obj, ACPI_PCIHP_IO_LEN_PROP, NULL); + object_property_get_uint(obj, ACPI_PCIHP_IO_LEN_PROP, NULL); } if (lpc) { obj = lpc; @@ -150,41 +149,42 @@ static void acpi_get_pm_info(AcpiPmInfo *pm) /* Fill in optional s3/s4 related properties */ o = object_property_get_qobject(obj, ACPI_PM_PROP_S3_DISABLED, NULL); if (o) { - pm->s3_disabled = qint_get_int(qobject_to_qint(o)); + pm->s3_disabled = qnum_get_uint(qobject_to_qnum(o)); } else { pm->s3_disabled = false; } qobject_decref(o); o = object_property_get_qobject(obj, ACPI_PM_PROP_S4_DISABLED, NULL); if (o) { - pm->s4_disabled = qint_get_int(qobject_to_qint(o)); + pm->s4_disabled = qnum_get_uint(qobject_to_qnum(o)); } else { pm->s4_disabled = false; } qobject_decref(o); o = object_property_get_qobject(obj, ACPI_PM_PROP_S4_VAL, NULL); if (o) { - pm->s4_val = qint_get_int(qobject_to_qint(o)); + pm->s4_val = qnum_get_uint(qobject_to_qnum(o)); } else { pm->s4_val = false; } qobject_decref(o); /* Fill in mandatory properties */ - pm->sci_int = object_property_get_int(obj, ACPI_PM_PROP_SCI_INT, NULL); - - pm->acpi_enable_cmd = object_property_get_int(obj, - ACPI_PM_PROP_ACPI_ENABLE_CMD, - NULL); - pm->acpi_disable_cmd = object_property_get_int(obj, - ACPI_PM_PROP_ACPI_DISABLE_CMD, - NULL); - pm->io_base = object_property_get_int(obj, ACPI_PM_PROP_PM_IO_BASE, - NULL); - pm->gpe0_blk = object_property_get_int(obj, ACPI_PM_PROP_GPE0_BLK, + pm->sci_int = object_property_get_uint(obj, ACPI_PM_PROP_SCI_INT, NULL); + + pm->acpi_enable_cmd = object_property_get_uint(obj, + ACPI_PM_PROP_ACPI_ENABLE_CMD, + NULL); + pm->acpi_disable_cmd = + object_property_get_uint(obj, + ACPI_PM_PROP_ACPI_DISABLE_CMD, + NULL); + pm->io_base = object_property_get_uint(obj, ACPI_PM_PROP_PM_IO_BASE, NULL); - pm->gpe0_blk_len = object_property_get_int(obj, ACPI_PM_PROP_GPE0_BLK_LEN, - NULL); + pm->gpe0_blk = object_property_get_uint(obj, ACPI_PM_PROP_GPE0_BLK, + NULL); + pm->gpe0_blk_len = object_property_get_uint(obj, ACPI_PM_PROP_GPE0_BLK_LEN, + NULL); pm->pcihp_bridge_en = object_property_get_bool(obj, "acpi-pci-hotplug-with-bridge-support", NULL); @@ -237,19 +237,19 @@ static void acpi_get_pci_holes(Range *hole, Range *hole64) g_assert(pci_host); range_set_bounds1(hole, - object_property_get_int(pci_host, - PCI_HOST_PROP_PCI_HOLE_START, - NULL), - object_property_get_int(pci_host, - PCI_HOST_PROP_PCI_HOLE_END, - NULL)); + object_property_get_uint(pci_host, + PCI_HOST_PROP_PCI_HOLE_START, + NULL), + object_property_get_uint(pci_host, + PCI_HOST_PROP_PCI_HOLE_END, + NULL)); range_set_bounds1(hole64, - object_property_get_int(pci_host, - PCI_HOST_PROP_PCI_HOLE64_START, - NULL), - object_property_get_int(pci_host, - PCI_HOST_PROP_PCI_HOLE64_END, - NULL)); + object_property_get_uint(pci_host, + PCI_HOST_PROP_PCI_HOLE64_START, + NULL), + object_property_get_uint(pci_host, + PCI_HOST_PROP_PCI_HOLE64_END, + NULL)); } #define ACPI_PORT_SMI_CMD 0x00b2 /* TODO: this is APM_CNT_IOPORT */ @@ -529,7 +529,7 @@ static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus, bsel = object_property_get_qobject(OBJECT(bus), ACPI_PCIHP_PROP_BSEL, NULL); if (bsel) { - int64_t bsel_val = qint_get_int(qobject_to_qint(bsel)); + uint64_t bsel_val = qnum_get_uint(qobject_to_qnum(bsel)); aml_append(parent_scope, aml_name_decl("BSEL", aml_int(bsel_val))); notify_method = aml_method("DVNT", 2, AML_NOTSERIALIZED); @@ -639,7 +639,8 @@ static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus, /* If bus supports hotplug select it and notify about local events */ if (bsel) { - int64_t bsel_val = qint_get_int(qobject_to_qint(bsel)); + uint64_t bsel_val = qnum_get_uint(qobject_to_qnum(bsel)); + aml_append(method, aml_store(aml_int(bsel_val), aml_name("BNUM"))); aml_append(method, aml_call2("DVNT", aml_name("PCIU"), aml_int(1) /* Device Check */) @@ -2614,12 +2615,12 @@ static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg) if (!o) { return false; } - mcfg->mcfg_base = qint_get_int(qobject_to_qint(o)); + mcfg->mcfg_base = qnum_get_uint(qobject_to_qnum(o)); qobject_decref(o); o = object_property_get_qobject(pci_host, PCIE_HOST_MCFG_SIZE, NULL); assert(o); - mcfg->mcfg_size = qint_get_int(qobject_to_qint(o)); + mcfg->mcfg_size = qnum_get_uint(qobject_to_qnum(o)); qobject_decref(o); return true; } diff --git a/hw/i386/pc.c b/hw/i386/pc.c index db41cca063..224fe58fe7 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -347,7 +347,7 @@ static int check_fdc(Object *obj, void *opaque) return 0; } - iobase = object_property_get_int(obj, "iobase", &local_err); + iobase = object_property_get_uint(obj, "iobase", &local_err); if (local_err || iobase != 0x3f0) { error_free(local_err); return 0; @@ -1098,7 +1098,7 @@ static void pc_new_cpu(const char *typename, int64_t apic_id, Error **errp) cpu = object_new(typename); - object_property_set_int(cpu, apic_id, "apic-id", &local_err); + object_property_set_uint(cpu, apic_id, "apic-id", &local_err); object_property_set_bool(cpu, true, "realized", &local_err); object_unref(cpu); @@ -1558,7 +1558,7 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, * and earlier, use IRQ2 for compat. Otherwise, use IRQ16~23, * IRQ8 and IRQ2. */ - uint8_t compat = object_property_get_int(OBJECT(hpet), + uint8_t compat = object_property_get_uint(OBJECT(hpet), HPET_INTCAP, NULL); if (!compat) { qdev_prop_set_uint32(hpet, HPET_INTCAP, hpet_irqs); diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c index 1acd4de405..cffa7e2017 100644 --- a/hw/i386/xen/xen-hvm.c +++ b/hw/i386/xen/xen-hvm.c @@ -182,9 +182,9 @@ static void xen_ram_init(PCMachineState *pcms, { MemoryRegion *sysmem = get_system_memory(); ram_addr_t block_len; - uint64_t user_lowmem = object_property_get_int(qdev_get_machine(), - PC_MACHINE_MAX_RAM_BELOW_4G, - &error_abort); + uint64_t user_lowmem = object_property_get_uint(qdev_get_machine(), + PC_MACHINE_MAX_RAM_BELOW_4G, + &error_abort); /* Handle the machine opt max-ram-below-4g. It is basically doing * min(xen limit, user limit). diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c index 1ef56f8d10..e1ac33042f 100644 --- a/hw/intc/apic_common.c +++ b/hw/intc/apic_common.c @@ -450,10 +450,10 @@ static void apic_common_get_id(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) { APICCommonState *s = APIC_COMMON(obj); - int64_t value; + uint32_t value; value = s->apicbase & MSR_IA32_APICBASE_EXTD ? s->initial_apic_id : s->id; - visit_type_int(v, name, &value, errp); + visit_type_uint32(v, name, &value, errp); } static void apic_common_set_id(Object *obj, Visitor *v, const char *name, @@ -462,14 +462,14 @@ static void apic_common_set_id(Object *obj, Visitor *v, const char *name, APICCommonState *s = APIC_COMMON(obj); DeviceState *dev = DEVICE(obj); Error *local_err = NULL; - int64_t value; + uint32_t value; if (dev->realized) { qdev_prop_set_after_realize(dev, name, errp); return; } - visit_type_int(v, name, &value, &local_err); + visit_type_uint32(v, name, &value, &local_err); if (local_err) { error_propagate(errp, local_err); return; @@ -484,7 +484,7 @@ static void apic_common_initfn(Object *obj) APICCommonState *s = APIC_COMMON(obj); s->id = s->initial_apic_id = -1; - object_property_add(obj, "id", "int", + object_property_add(obj, "id", "uint32", apic_common_get_id, apic_common_set_id, NULL, NULL, NULL); } diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c index 4228b7ca00..410915a2ac 100644 --- a/hw/intc/arm_gicv3_common.c +++ b/hw/intc/arm_gicv3_common.c @@ -268,7 +268,7 @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp) * VLPIS == 0 (virtual LPIs not supported) * PLPIS == 0 (physical LPIs not supported) */ - cpu_affid = object_property_get_int(OBJECT(cpu), "mp-affinity", NULL); + cpu_affid = object_property_get_uint(OBJECT(cpu), "mp-affinity", NULL); last = (i == s->num_cpu - 1); /* The CPU mp-affinity property is in MPIDR register format; squash diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c index 9e8dab0e89..b72258e28f 100644 --- a/hw/mem/pc-dimm.c +++ b/hw/mem/pc-dimm.c @@ -46,7 +46,8 @@ void pc_dimm_memory_plug(DeviceState *dev, MemoryHotplugState *hpms, uint64_t existing_dimms_capacity = 0; uint64_t addr; - addr = object_property_get_int(OBJECT(dimm), PC_DIMM_ADDR_PROP, &local_err); + addr = object_property_get_uint(OBJECT(dimm), + PC_DIMM_ADDR_PROP, &local_err); if (local_err) { goto out; } @@ -73,7 +74,7 @@ void pc_dimm_memory_plug(DeviceState *dev, MemoryHotplugState *hpms, goto out; } - object_property_set_int(OBJECT(dev), addr, PC_DIMM_ADDR_PROP, &local_err); + object_property_set_uint(OBJECT(dev), addr, PC_DIMM_ADDR_PROP, &local_err); if (local_err) { goto out; } @@ -135,7 +136,7 @@ static int pc_existing_dimms_capacity_internal(Object *obj, void *opaque) DeviceState *dev = DEVICE(obj); if (dev->realized) { - (*size) += object_property_get_int(obj, PC_DIMM_SIZE_PROP, + (*size) += object_property_get_uint(obj, PC_DIMM_SIZE_PROP, cap->errp); } @@ -181,8 +182,8 @@ int qmp_pc_dimm_device_list(Object *obj, void *opaque) di->addr = dimm->addr; di->slot = dimm->slot; di->node = dimm->node; - di->size = object_property_get_int(OBJECT(dimm), PC_DIMM_SIZE_PROP, - NULL); + di->size = object_property_get_uint(OBJECT(dimm), PC_DIMM_SIZE_PROP, + NULL); di->memdev = object_get_canonical_path(OBJECT(dimm->hostmem)); info->u.dimm.data = di; @@ -313,9 +314,9 @@ uint64_t pc_dimm_get_free_addr(uint64_t address_space_start, /* find address range that will fit new DIMM */ for (item = list; item; item = g_slist_next(item)) { PCDIMMDevice *dimm = item->data; - uint64_t dimm_size = object_property_get_int(OBJECT(dimm), - PC_DIMM_SIZE_PROP, - errp); + uint64_t dimm_size = object_property_get_uint(OBJECT(dimm), + PC_DIMM_SIZE_PROP, + errp); if (errp && *errp) { goto out; } @@ -355,7 +356,7 @@ static Property pc_dimm_properties[] = { static void pc_dimm_get_size(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) { - int64_t value; + uint64_t value; MemoryRegion *mr; PCDIMMDevice *dimm = PC_DIMM(obj); PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(obj); @@ -363,7 +364,7 @@ static void pc_dimm_get_size(Object *obj, Visitor *v, const char *name, mr = ddc->get_memory_region(dimm); value = memory_region_size(mr); - visit_type_int(v, name, &value, errp); + visit_type_uint64(v, name, &value, errp); } static void pc_dimm_check_memdev_is_busy(Object *obj, const char *name, @@ -386,7 +387,7 @@ static void pc_dimm_init(Object *obj) { PCDIMMDevice *dimm = PC_DIMM(obj); - object_property_add(obj, PC_DIMM_SIZE_PROP, "int", pc_dimm_get_size, + object_property_add(obj, PC_DIMM_SIZE_PROP, "uint64", pc_dimm_get_size, NULL, NULL, NULL, &error_abort); object_property_add_link(obj, PC_DIMM_MEMDEV_PROP, TYPE_MEMORY_BACKEND, (Object **)&dimm->hostmem, diff --git a/hw/misc/auxbus.c b/hw/misc/auxbus.c index e4a7ba41de..8a90ddda84 100644 --- a/hw/misc/auxbus.c +++ b/hw/misc/auxbus.c @@ -244,7 +244,7 @@ static void aux_slave_dev_print(Monitor *mon, DeviceState *dev, int indent) monitor_printf(mon, "%*smemory " TARGET_FMT_plx "/" TARGET_FMT_plx "\n", indent, "", - object_property_get_int(OBJECT(s->mmio), "addr", NULL), + object_property_get_uint(OBJECT(s->mmio), "addr", NULL), memory_region_size(s->mmio)); } diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c index 57da7f2199..2b1e9a6450 100644 --- a/hw/misc/pvpanic.c +++ b/hw/misc/pvpanic.c @@ -111,7 +111,7 @@ uint16_t pvpanic_port(void) if (!o) { return 0; } - return object_property_get_int(o, PVPANIC_IOPORT_PROP, NULL); + return object_property_get_uint(o, PVPANIC_IOPORT_PROP, NULL); } static Property pvpanic_isa_properties[] = { diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c index 6e234938db..0e0a1dc888 100644 --- a/hw/net/e1000e.c +++ b/hw/net/e1000e.c @@ -645,12 +645,12 @@ static PropertyInfo e1000e_prop_disable_vnet, static Property e1000e_properties[] = { DEFINE_NIC_PROPERTIES(E1000EState, conf), - DEFINE_PROP_DEFAULT("disable_vnet_hdr", E1000EState, disable_vnet, false, + DEFINE_PROP_SIGNED("disable_vnet_hdr", E1000EState, disable_vnet, false, e1000e_prop_disable_vnet, bool), - DEFINE_PROP_DEFAULT("subsys_ven", E1000EState, subsys_ven, + DEFINE_PROP_SIGNED("subsys_ven", E1000EState, subsys_ven, PCI_VENDOR_ID_INTEL, e1000e_prop_subsys_ven, uint16_t), - DEFINE_PROP_DEFAULT("subsys", E1000EState, subsys, 0, + DEFINE_PROP_SIGNED("subsys", E1000EState, subsys, 0, e1000e_prop_subsys, uint16_t), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/pci-host/gpex.c b/hw/pci-host/gpex.c index e2629ce70d..83084b9aab 100644 --- a/hw/pci-host/gpex.c +++ b/hw/pci-host/gpex.c @@ -94,7 +94,7 @@ static void gpex_host_initfn(Object *obj) object_initialize(root, sizeof(*root), TYPE_GPEX_ROOT_DEVICE); object_property_add_child(obj, "gpex_root", OBJECT(root), NULL); - qdev_prop_set_uint32(DEVICE(root), "addr", PCI_DEVFN(0, 0)); + qdev_prop_set_int32(DEVICE(root), "addr", PCI_DEVFN(0, 0)); qdev_prop_set_bit(DEVICE(root), "multifunction", false); } diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c index 4ce201ea65..a2c1033dbe 100644 --- a/hw/pci-host/piix.c +++ b/hw/pci-host/piix.c @@ -273,19 +273,19 @@ static void i440fx_pcihost_initfn(Object *obj) memory_region_init_io(&s->data_mem, obj, &pci_host_data_le_ops, s, "pci-conf-data", 4); - object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "int", + object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "uint32", i440fx_pcihost_get_pci_hole_start, NULL, NULL, NULL, NULL); - object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_END, "int", + object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_END, "uint32", i440fx_pcihost_get_pci_hole_end, NULL, NULL, NULL, NULL); - object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_START, "int", + object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_START, "uint64", i440fx_pcihost_get_pci_hole64_start, NULL, NULL, NULL, NULL); - object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_END, "int", + object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_END, "uint64", i440fx_pcihost_get_pci_hole64_end, NULL, NULL, NULL, NULL); } diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c index 28cb97b60f..0e472f2ed4 100644 --- a/hw/pci-host/q35.c +++ b/hw/pci-host/q35.c @@ -129,9 +129,8 @@ static void q35_host_get_mmcfg_size(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) { PCIExpressHost *e = PCIE_HOST_BRIDGE(obj); - uint32_t value = e->size; - visit_type_uint32(v, name, &value, errp); + visit_type_uint64(v, name, &e->size, errp); } static Property q35_host_props[] = { @@ -173,26 +172,26 @@ static void q35_host_initfn(Object *obj) object_initialize(&s->mch, sizeof(s->mch), TYPE_MCH_PCI_DEVICE); object_property_add_child(OBJECT(s), "mch", OBJECT(&s->mch), NULL); - qdev_prop_set_uint32(DEVICE(&s->mch), "addr", PCI_DEVFN(0, 0)); + qdev_prop_set_int32(DEVICE(&s->mch), "addr", PCI_DEVFN(0, 0)); qdev_prop_set_bit(DEVICE(&s->mch), "multifunction", false); - object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "int", + object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "uint32", q35_host_get_pci_hole_start, NULL, NULL, NULL, NULL); - object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_END, "int", + object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_END, "uint32", q35_host_get_pci_hole_end, NULL, NULL, NULL, NULL); - object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_START, "int", + object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_START, "uint64", q35_host_get_pci_hole64_start, NULL, NULL, NULL, NULL); - object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_END, "int", + object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_END, "uint64", q35_host_get_pci_hole64_end, NULL, NULL, NULL, NULL); - object_property_add(obj, PCIE_HOST_MCFG_SIZE, "int", + object_property_add(obj, PCIE_HOST_MCFG_SIZE, "uint64", q35_host_get_mmcfg_size, NULL, NULL, NULL, NULL); diff --git a/hw/pci-host/xilinx-pcie.c b/hw/pci-host/xilinx-pcie.c index a968cea2af..2c78dcfc26 100644 --- a/hw/pci-host/xilinx-pcie.c +++ b/hw/pci-host/xilinx-pcie.c @@ -150,7 +150,7 @@ static void xilinx_pcie_host_init(Object *obj) object_initialize(root, sizeof(*root), TYPE_XILINX_PCIE_ROOT); object_property_add_child(obj, "root", OBJECT(root), NULL); - qdev_prop_set_uint32(DEVICE(root), "addr", PCI_DEVFN(0, 0)); + qdev_prop_set_int32(DEVICE(root), "addr", PCI_DEVFN(0, 0)); qdev_prop_set_bit(DEVICE(root), "multifunction", false); } diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index 89b6801f67..a4cd733cba 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -1111,7 +1111,7 @@ static void powernv_machine_initfn(Object *obj) static void powernv_machine_class_props_init(ObjectClass *oc) { - object_class_property_add(oc, "num-chips", "uint32_t", + object_class_property_add(oc, "num-chips", "uint32", pnv_get_num_chips, pnv_set_num_chips, NULL, NULL, NULL); object_class_property_set_description(oc, "num-chips", diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index c7b00b610c..67264830db 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -51,7 +51,7 @@ static void powernv_cpu_init(PowerPCCPU *cpu, Error **errp) int thread_index = 0; /* TODO: TCG supports only one thread */ ppc_spr_t *pir = &env->spr_cb[SPR_PIR]; - core_pir = object_property_get_int(OBJECT(cpu), "core-pir", &error_abort); + core_pir = object_property_get_uint(OBJECT(cpu), "core-pir", &error_abort); /* * The PIR of a thread is the core PIR + the thread index. We will diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index e877d45db8..ede5167bc0 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2589,7 +2589,8 @@ static void spapr_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev, goto out; } - addr = object_property_get_int(OBJECT(dimm), PC_DIMM_ADDR_PROP, &local_err); + addr = object_property_get_uint(OBJECT(dimm), + PC_DIMM_ADDR_PROP, &local_err); if (local_err) { pc_dimm_memory_unplug(dev, &ms->hotplug_memory, mr); goto out; @@ -2751,7 +2752,7 @@ static void spapr_memory_unplug_request(HotplugHandler *hotplug_dev, sPAPRDRConnector *drc; sPAPRDIMMState *ds; - addr_start = object_property_get_int(OBJECT(dimm), PC_DIMM_ADDR_PROP, + addr_start = object_property_get_uint(OBJECT(dimm), PC_DIMM_ADDR_PROP, &local_err); if (local_err) { goto out; @@ -2986,7 +2987,7 @@ static void spapr_machine_device_plug(HotplugHandler *hotplug_dev, error_setg(errp, "Memory hotplug not supported for this machine"); return; } - node = object_property_get_int(OBJECT(dev), PC_DIMM_NODE_PROP, errp); + node = object_property_get_uint(OBJECT(dev), PC_DIMM_NODE_PROP, errp); if (*errp) { return; } diff --git a/hw/usb/xen-usb.c b/hw/usb/xen-usb.c index fe62183fe3..584a6f2442 100644 --- a/hw/usb/xen-usb.c +++ b/hw/usb/xen-usb.c @@ -30,7 +30,6 @@ #include "hw/xen/xen_backend.h" #include "monitor/qdev.h" #include "qapi/qmp/qbool.h" -#include "qapi/qmp/qint.h" #include "qapi/qmp/qstring.h" #include "hw/xen/io/ring.h" diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h index c2fdd70cdc..95593408ef 100644 --- a/include/hw/isa/isa.h +++ b/include/hw/isa/isa.h @@ -29,7 +29,7 @@ static inline uint16_t applesmc_port(void) Object *obj = object_resolve_path_type("", TYPE_APPLE_SMC, NULL); if (obj) { - return object_property_get_int(obj, APPLESMC_PROP_IO_BASE, NULL); + return object_property_get_uint(obj, APPLESMC_PROP_IO_BASE, NULL); } return 0; } diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index e69489ec6c..9d7c1c0e9b 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -226,8 +226,10 @@ struct Property { PropertyInfo *info; ptrdiff_t offset; uint8_t bitnr; - QType qtype; - int64_t defval; + union { + int64_t i; + uint64_t u; + } defval; int arrayoffset; PropertyInfo *arrayinfo; int arrayfieldsize; @@ -238,6 +240,7 @@ struct PropertyInfo { const char *description; const char * const *enum_table; int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len); + void (*set_default_value)(Object *obj, const Property *prop); ObjectPropertyAccessor *get; ObjectPropertyAccessor *set; ObjectPropertyRelease *release; diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h index d206fc93dd..1e5c928f32 100644 --- a/include/hw/qdev-properties.h +++ b/include/hw/qdev-properties.h @@ -37,31 +37,39 @@ extern PropertyInfo qdev_prop_arraylen; .offset = offsetof(_state, _field) \ + type_check(_type, typeof_field(_state, _field)), \ } -#define DEFINE_PROP_DEFAULT(_name, _state, _field, _defval, _prop, _type) { \ + +#define DEFINE_PROP_SIGNED(_name, _state, _field, _defval, _prop, _type) { \ .name = (_name), \ .info = &(_prop), \ .offset = offsetof(_state, _field) \ + type_check(_type,typeof_field(_state, _field)), \ - .qtype = QTYPE_QINT, \ - .defval = (_type)_defval, \ + .defval.i = (_type)_defval, \ } + #define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) { \ .name = (_name), \ .info = &(qdev_prop_bit), \ .bitnr = (_bit), \ .offset = offsetof(_state, _field) \ + type_check(uint32_t,typeof_field(_state, _field)), \ - .qtype = QTYPE_QBOOL, \ - .defval = (bool)_defval, \ + .defval.u = (bool)_defval, \ + } + +#define DEFINE_PROP_UNSIGNED(_name, _state, _field, _defval, _prop, _type) { \ + .name = (_name), \ + .info = &(_prop), \ + .offset = offsetof(_state, _field) \ + + type_check(_type, typeof_field(_state, _field)), \ + .defval.u = (_type)_defval, \ } + #define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval) { \ .name = (_name), \ .info = &(qdev_prop_bit64), \ .bitnr = (_bit), \ .offset = offsetof(_state, _field) \ + type_check(uint64_t, typeof_field(_state, _field)), \ - .qtype = QTYPE_QBOOL, \ - .defval = (bool)_defval, \ + .defval.u = (bool)_defval, \ } #define DEFINE_PROP_BOOL(_name, _state, _field, _defval) { \ @@ -69,8 +77,7 @@ extern PropertyInfo qdev_prop_arraylen; .info = &(qdev_prop_bool), \ .offset = offsetof(_state, _field) \ + type_check(bool, typeof_field(_state, _field)), \ - .qtype = QTYPE_QBOOL, \ - .defval = (bool)_defval, \ + .defval.u = (bool)_defval, \ } #define PROP_ARRAY_LEN_PREFIX "len-" @@ -105,26 +112,25 @@ extern PropertyInfo qdev_prop_arraylen; .info = &(qdev_prop_arraylen), \ .offset = offsetof(_state, _field) \ + type_check(uint32_t, typeof_field(_state, _field)), \ - .qtype = QTYPE_QINT, \ .arrayinfo = &(_arrayprop), \ .arrayfieldsize = sizeof(_arraytype), \ .arrayoffset = offsetof(_state, _arrayfield), \ } #define DEFINE_PROP_UINT8(_n, _s, _f, _d) \ - DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint8, uint8_t) + DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, qdev_prop_uint8, uint8_t) #define DEFINE_PROP_UINT16(_n, _s, _f, _d) \ - DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint16, uint16_t) + DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, qdev_prop_uint16, uint16_t) #define DEFINE_PROP_UINT32(_n, _s, _f, _d) \ - DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint32, uint32_t) + DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, qdev_prop_uint32, uint32_t) #define DEFINE_PROP_INT32(_n, _s, _f, _d) \ - DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_int32, int32_t) + DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_int32, int32_t) #define DEFINE_PROP_UINT64(_n, _s, _f, _d) \ - DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint64, uint64_t) + DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, qdev_prop_uint64, uint64_t) #define DEFINE_PROP_SIZE(_n, _s, _f, _d) \ - DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_size, uint64_t) + DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, qdev_prop_size, uint64_t) #define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d) \ - DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_pci_devfn, int32_t) + DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_pci_devfn, int32_t) /* * Please avoid pointer properties. If you must use them, you must @@ -158,17 +164,17 @@ extern PropertyInfo qdev_prop_arraylen; #define DEFINE_PROP_MACADDR(_n, _s, _f) \ DEFINE_PROP(_n, _s, _f, qdev_prop_macaddr, MACAddr) #define DEFINE_PROP_ON_OFF_AUTO(_n, _s, _f, _d) \ - DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_on_off_auto, OnOffAuto) + DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_on_off_auto, OnOffAuto) #define DEFINE_PROP_LOSTTICKPOLICY(_n, _s, _f, _d) \ - DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_losttickpolicy, \ + DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_losttickpolicy, \ LostTickPolicy) #define DEFINE_PROP_BLOCKDEV_ON_ERROR(_n, _s, _f, _d) \ - DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_blockdev_on_error, \ + DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_blockdev_on_error, \ BlockdevOnError) #define DEFINE_PROP_BIOS_CHS_TRANS(_n, _s, _f, _d) \ - DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_bios_chs_trans, int) + DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_bios_chs_trans, int) #define DEFINE_PROP_BLOCKSIZE(_n, _s, _f) \ - DEFINE_PROP_DEFAULT(_n, _s, _f, 0, qdev_prop_blocksize, uint16_t) + DEFINE_PROP_UNSIGNED(_n, _s, _f, 0, qdev_prop_blocksize, uint16_t) #define DEFINE_PROP_PCI_HOST_DEVADDR(_n, _s, _f) \ DEFINE_PROP(_n, _s, _f, qdev_prop_pci_host_devaddr, PCIHostDeviceAddress) diff --git a/include/qapi/qmp/qdict.h b/include/qapi/qmp/qdict.h index 188440a6a8..363e431106 100644 --- a/include/qapi/qmp/qdict.h +++ b/include/qapi/qmp/qdict.h @@ -15,6 +15,7 @@ #include "qapi/qmp/qobject.h" #include "qapi/qmp/qlist.h" +#include "qapi/qmp/qnum.h" #include "qemu/queue.h" #define QDICT_BUCKET_MAX 512 @@ -54,7 +55,7 @@ void qdict_destroy_obj(QObject *obj); /* Helpers for int, bool, and string */ #define qdict_put_int(qdict, key, value) \ - qdict_put(qdict, key, qint_from_int(value)) + qdict_put(qdict, key, qnum_from_int(value)) #define qdict_put_bool(qdict, key, value) \ qdict_put(qdict, key, qbool_from_bool(value)) #define qdict_put_str(qdict, key, value) \ diff --git a/include/qapi/qmp/qfloat.h b/include/qapi/qmp/qfloat.h deleted file mode 100644 index b5d15836b5..0000000000 --- a/include/qapi/qmp/qfloat.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * QFloat Module - * - * Copyright IBM, Corp. 2009 - * - * Authors: - * Anthony Liguori <aliguori@us.ibm.com> - * - * 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. - * - */ - -#ifndef QFLOAT_H -#define QFLOAT_H - -#include "qapi/qmp/qobject.h" - -typedef struct QFloat { - QObject base; - double value; -} QFloat; - -QFloat *qfloat_from_double(double value); -double qfloat_get_double(const QFloat *qi); -QFloat *qobject_to_qfloat(const QObject *obj); -void qfloat_destroy_obj(QObject *obj); - -#endif /* QFLOAT_H */ diff --git a/include/qapi/qmp/qint.h b/include/qapi/qmp/qint.h deleted file mode 100644 index 3aaff768dd..0000000000 --- a/include/qapi/qmp/qint.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * QInt Module - * - * Copyright (C) 2009 Red Hat Inc. - * - * Authors: - * Luiz Capitulino <lcapitulino@redhat.com> - * - * 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. - */ - -#ifndef QINT_H -#define QINT_H - -#include "qapi/qmp/qobject.h" - -typedef struct QInt { - QObject base; - int64_t value; -} QInt; - -QInt *qint_from_int(int64_t value); -int64_t qint_get_int(const QInt *qi); -QInt *qobject_to_qint(const QObject *obj); -void qint_destroy_obj(QObject *obj); - -#endif /* QINT_H */ diff --git a/include/qapi/qmp/qlist.h b/include/qapi/qmp/qlist.h index 5dc4ed9616..c4b5fdad9b 100644 --- a/include/qapi/qmp/qlist.h +++ b/include/qapi/qmp/qlist.h @@ -14,6 +14,7 @@ #define QLIST_H #include "qapi/qmp/qobject.h" +#include "qapi/qmp/qnum.h" #include "qemu/queue.h" typedef struct QListEntry { @@ -31,7 +32,7 @@ typedef struct QList { /* Helpers for int, bool, and string */ #define qlist_append_int(qlist, value) \ - qlist_append(qlist, qint_from_int(value)) + qlist_append(qlist, qnum_from_int(value)) #define qlist_append_bool(qlist, value) \ qlist_append(qlist, qbool_from_bool(value)) #define qlist_append_str(qlist, value) \ diff --git a/include/qapi/qmp/qnum.h b/include/qapi/qmp/qnum.h new file mode 100644 index 0000000000..09d745c490 --- /dev/null +++ b/include/qapi/qmp/qnum.h @@ -0,0 +1,53 @@ +/* + * QNum Module + * + * Copyright (C) 2009 Red Hat Inc. + * + * Authors: + * Luiz Capitulino <lcapitulino@redhat.com> + * Anthony Liguori <aliguori@us.ibm.com> + * Marc-André Lureau <marcandre.lureau@redhat.com> + * + * 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. + */ + +#ifndef QNUM_H +#define QNUM_H + +#include "qapi/qmp/qobject.h" + +typedef enum { + QNUM_I64, + QNUM_U64, + QNUM_DOUBLE +} QNumKind; + +typedef struct QNum { + QObject base; + QNumKind kind; + union { + int64_t i64; + uint64_t u64; + double dbl; + } u; +} QNum; + +QNum *qnum_from_int(int64_t value); +QNum *qnum_from_uint(uint64_t value); +QNum *qnum_from_double(double value); + +bool qnum_get_try_int(const QNum *qn, int64_t *val); +int64_t qnum_get_int(const QNum *qn); + +bool qnum_get_try_uint(const QNum *qn, uint64_t *val); +uint64_t qnum_get_uint(const QNum *qn); + +double qnum_get_double(QNum *qn); + +char *qnum_to_string(QNum *qn); + +QNum *qobject_to_qnum(const QObject *obj); +void qnum_destroy_obj(QObject *obj); + +#endif /* QNUM_H */ diff --git a/include/qapi/qmp/types.h b/include/qapi/qmp/types.h index 27cfbd84e5..a4bc662bfb 100644 --- a/include/qapi/qmp/types.h +++ b/include/qapi/qmp/types.h @@ -14,8 +14,7 @@ #define QAPI_QMP_TYPES_H #include "qapi/qmp/qobject.h" -#include "qapi/qmp/qint.h" -#include "qapi/qmp/qfloat.h" +#include "qapi/qmp/qnum.h" #include "qapi/qmp/qbool.h" #include "qapi/qmp/qstring.h" #include "qapi/qmp/qdict.h" diff --git a/include/qapi/qobject-input-visitor.h b/include/qapi/qobject-input-visitor.h index b399285c43..daee18c6ac 100644 --- a/include/qapi/qobject-input-visitor.h +++ b/include/qapi/qobject-input-visitor.h @@ -30,9 +30,9 @@ typedef struct QObjectInputVisitor QObjectInputVisitor; * visit_type_FOO() creates an instance of QAPI type FOO. The visited * QObject must match FOO. QDict matches struct/union types, QList * matches list types, QString matches type 'str' and enumeration - * types, QInt matches integer types, QFloat matches type 'number', - * QBool matches type 'bool'. Type 'any' is matched by QObject. A - * QAPI alternate type is matched when one of its member types is. + * types, QNum matches integer and float types, QBool matches type + * 'bool'. Type 'any' is matched by QObject. A QAPI alternate type + * is matched when one of its member types is. * * visit_start_struct() ... visit_end_struct() visits a QDict and * creates a QAPI struct/union. Visits in between visit the diff --git a/include/qapi/qobject-output-visitor.h b/include/qapi/qobject-output-visitor.h index 9b990c318e..e5a3490812 100644 --- a/include/qapi/qobject-output-visitor.h +++ b/include/qapi/qobject-output-visitor.h @@ -28,10 +28,10 @@ typedef struct QObjectOutputVisitor QObjectOutputVisitor; * * visit_type_FOO() creates a QObject for QAPI type FOO. It creates a * QDict for struct/union types, a QList for list types, QString for - * type 'str' and enumeration types, QInt for integer types, QFloat - * for type 'number', QBool for type 'bool'. For type 'any', it - * increments the QObject's reference count. For QAPI alternate - * types, it creates the QObject for the member that is in use. + * type 'str' and enumeration types, QNum for integer and float + * types, QBool for type 'bool'. For type 'any', it increments the + * QObject's reference count. For QAPI alternate types, it creates + * the QObject for the member that is in use. * * visit_start_struct() ... visit_end_struct() visits a QAPI * struct/union and creates a QDict. Visits in between visit the diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h index e87709db5c..dcd656ab76 100644 --- a/include/qapi/visitor-impl.h +++ b/include/qapi/visitor-impl.h @@ -71,7 +71,7 @@ struct Visitor * optional for output visitors. */ void (*start_alternate)(Visitor *v, const char *name, GenericAlternate **obj, size_t size, - bool promote_int, Error **errp); + Error **errp); /* Optional, needed for dealloc visitor */ void (*end_alternate)(Visitor *v, void **obj); diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h index 4721c39ae3..74768aabda 100644 --- a/include/qapi/visitor.h +++ b/include/qapi/visitor.h @@ -410,15 +410,13 @@ void visit_end_list(Visitor *v, void **list); * the qtype of the next thing to be visited, stored in (*@obj)->type. * Other visitors will leave @obj unchanged. * - * If @promote_int, treat integers as QTYPE_FLOAT. - * * If successful, this must be paired with visit_end_alternate() with * the same @obj to clean up, even if visiting the contents of the * alternate fails. */ void visit_start_alternate(Visitor *v, const char *name, GenericAlternate **obj, size_t size, - bool promote_int, Error **errp); + Error **errp); /* * Finish visiting an alternate type. diff --git a/include/qom/object.h b/include/qom/object.h index cd0f412ce9..abaeb8cf4e 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -1094,6 +1094,29 @@ int64_t object_property_get_int(Object *obj, const char *name, Error **errp); /** + * object_property_set_uint: + * @value: the value to be written to the property + * @name: the name of the property + * @errp: returns an error if this function fails + * + * Writes an unsigned integer value to a property. + */ +void object_property_set_uint(Object *obj, uint64_t value, + const char *name, Error **errp); + +/** + * object_property_get_uint: + * @obj: the object + * @name: the name of the property + * @errp: returns an error if this function fails + * + * Returns: the value of the property, converted to an unsigned integer, or 0 + * an error occurs (including when the property value is not an integer). + */ +uint64_t object_property_get_uint(Object *obj, const char *name, + Error **errp); + +/** * object_property_get_enum: * @obj: the object * @name: the name of the property @@ -2974,7 +2974,7 @@ static QDict *monitor_parse_arguments(Monitor *mon, monitor_printf(mon, "Unknown unit suffix\n"); goto fail; } - qdict_put(qdict, key, qfloat_from_double(val)); + qdict_put(qdict, key, qnum_from_double(val)); } break; case 'b': diff --git a/net/dump.c b/net/dump.c index 442eb532f9..15df9a4973 100644 --- a/net/dump.c +++ b/net/dump.c @@ -328,7 +328,7 @@ static void filter_dump_instance_init(Object *obj) nfds->maxlen = 65536; - object_property_add(obj, "maxlen", "int", filter_dump_get_maxlen, + object_property_add(obj, "maxlen", "uint32", filter_dump_get_maxlen, filter_dump_set_maxlen, NULL, NULL, NULL); object_property_add_str(obj, "file", file_dump_get_filename, file_dump_set_filename, NULL); diff --git a/net/filter-buffer.c b/net/filter-buffer.c index cc6bd94445..9ce96aaa35 100644 --- a/net/filter-buffer.c +++ b/net/filter-buffer.c @@ -191,7 +191,7 @@ out: static void filter_buffer_init(Object *obj) { - object_property_add(obj, "interval", "int", + object_property_add(obj, "interval", "uint32", filter_buffer_get_interval, filter_buffer_set_interval, NULL, NULL, NULL); } @@ -216,7 +216,7 @@ static void parse_numa_node(MachineState *ms, NumaNodeOptions *node, } object_ref(o); - numa_info[nodenr].node_mem = object_property_get_int(o, "size", NULL); + numa_info[nodenr].node_mem = object_property_get_uint(o, "size", NULL); numa_info[nodenr].node_memdev = MEMORY_BACKEND(o); } numa_info[nodenr].present = true; @@ -641,8 +641,8 @@ static int query_memdev(Object *obj, void *opaque) m->value->id = object_property_get_str(obj, "id", NULL); m->value->has_id = !!m->value->id; - m->value->size = object_property_get_int(obj, "size", - &error_abort); + m->value->size = object_property_get_uint(obj, "size", + &error_abort); m->value->merge = object_property_get_bool(obj, "merge", &error_abort); m->value->dump = object_property_get_bool(obj, "dump", diff --git a/qapi/qapi-clone-visitor.c b/qapi/qapi-clone-visitor.c index de756bfb33..ed16d3a17f 100644 --- a/qapi/qapi-clone-visitor.c +++ b/qapi/qapi-clone-visitor.c @@ -70,7 +70,7 @@ static GenericList *qapi_clone_next_list(Visitor *v, GenericList *tail, static void qapi_clone_start_alternate(Visitor *v, const char *name, GenericAlternate **obj, size_t size, - bool promote_int, Error **errp) + Error **errp) { qapi_clone_start_struct(v, name, (void **)obj, size, errp); } diff --git a/qapi/qapi-dealloc-visitor.c b/qapi/qapi-dealloc-visitor.c index e39457bc79..fd6f9fb61c 100644 --- a/qapi/qapi-dealloc-visitor.c +++ b/qapi/qapi-dealloc-visitor.c @@ -38,7 +38,7 @@ static void qapi_dealloc_end_struct(Visitor *v, void **obj) static void qapi_dealloc_start_alternate(Visitor *v, const char *name, GenericAlternate **obj, size_t size, - bool promote_int, Error **errp) + Error **errp) { } diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c index 43a09d147d..935a2c5bc9 100644 --- a/qapi/qapi-visit-core.c +++ b/qapi/qapi-visit-core.c @@ -106,15 +106,15 @@ void visit_end_list(Visitor *v, void **obj) void visit_start_alternate(Visitor *v, const char *name, GenericAlternate **obj, size_t size, - bool promote_int, Error **errp) + Error **errp) { Error *err = NULL; assert(obj && size >= sizeof(GenericAlternate)); assert(!(v->type & VISITOR_OUTPUT) || *obj); - trace_visit_start_alternate(v, name, obj, size, promote_int); + trace_visit_start_alternate(v, name, obj, size); if (v->start_alternate) { - v->start_alternate(v, name, obj, size, promote_int, &err); + v->start_alternate(v, name, obj, size, &err); } if (v->type & VISITOR_INPUT) { assert(v->start_alternate && !err != !*obj); diff --git a/qapi/qobject-input-visitor.c b/qapi/qobject-input-visitor.c index eac40f618a..35aff78f2b 100644 --- a/qapi/qobject-input-visitor.c +++ b/qapi/qobject-input-visitor.c @@ -367,7 +367,7 @@ static void qobject_input_end_list(Visitor *v, void **obj) static void qobject_input_start_alternate(Visitor *v, const char *name, GenericAlternate **obj, size_t size, - bool promote_int, Error **errp) + Error **errp) { QObjectInputVisitor *qiv = to_qiv(v); QObject *qobj = qobject_input_get_object(qiv, name, false, errp); @@ -378,9 +378,6 @@ static void qobject_input_start_alternate(Visitor *v, const char *name, } *obj = g_malloc0(size); (*obj)->type = qobject_type(qobj); - if (promote_int && (*obj)->type == QTYPE_QINT) { - (*obj)->type = QTYPE_QFLOAT; - } } static void qobject_input_type_int64(Visitor *v, const char *name, int64_t *obj, @@ -388,22 +385,18 @@ static void qobject_input_type_int64(Visitor *v, const char *name, int64_t *obj, { QObjectInputVisitor *qiv = to_qiv(v); QObject *qobj = qobject_input_get_object(qiv, name, true, errp); - QInt *qint; + QNum *qnum; if (!qobj) { return; } - qint = qobject_to_qint(qobj); - if (!qint) { + qnum = qobject_to_qnum(qobj); + if (!qnum || !qnum_get_try_int(qnum, obj)) { error_setg(errp, QERR_INVALID_PARAMETER_TYPE, full_name(qiv, name), "integer"); - return; } - - *obj = qint_get_int(qint); } - static void qobject_input_type_int64_keyval(Visitor *v, const char *name, int64_t *obj, Error **errp) { @@ -424,22 +417,32 @@ static void qobject_input_type_int64_keyval(Visitor *v, const char *name, static void qobject_input_type_uint64(Visitor *v, const char *name, uint64_t *obj, Error **errp) { - /* FIXME: qobject_to_qint mishandles values over INT64_MAX */ QObjectInputVisitor *qiv = to_qiv(v); QObject *qobj = qobject_input_get_object(qiv, name, true, errp); - QInt *qint; + QNum *qnum; + int64_t val; if (!qobj) { return; } - qint = qobject_to_qint(qobj); - if (!qint) { - error_setg(errp, QERR_INVALID_PARAMETER_TYPE, - full_name(qiv, name), "integer"); + qnum = qobject_to_qnum(qobj); + if (!qnum) { + goto err; + } + + if (qnum_get_try_uint(qnum, obj)) { return; } - *obj = qint_get_int(qint); + /* Need to accept negative values for backward compatibility */ + if (qnum_get_try_int(qnum, &val)) { + *obj = val; + return; + } + +err: + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, + full_name(qiv, name), "uint64"); } static void qobject_input_type_uint64_keyval(Visitor *v, const char *name, @@ -534,26 +537,19 @@ static void qobject_input_type_number(Visitor *v, const char *name, double *obj, { QObjectInputVisitor *qiv = to_qiv(v); QObject *qobj = qobject_input_get_object(qiv, name, true, errp); - QInt *qint; - QFloat *qfloat; + QNum *qnum; if (!qobj) { return; } - qint = qobject_to_qint(qobj); - if (qint) { - *obj = qint_get_int(qobject_to_qint(qobj)); - return; - } - - qfloat = qobject_to_qfloat(qobj); - if (qfloat) { - *obj = qfloat_get_double(qobject_to_qfloat(qobj)); + qnum = qobject_to_qnum(qobj); + if (!qnum) { + error_setg(errp, QERR_INVALID_PARAMETER_TYPE, + full_name(qiv, name), "number"); return; } - error_setg(errp, QERR_INVALID_PARAMETER_TYPE, - full_name(qiv, name), "number"); + *obj = qnum_get_double(qnum); } static void qobject_input_type_number_keyval(Visitor *v, const char *name, diff --git a/qapi/qobject-output-visitor.c b/qapi/qobject-output-visitor.c index 871127079d..70be84ccb5 100644 --- a/qapi/qobject-output-visitor.c +++ b/qapi/qobject-output-visitor.c @@ -144,15 +144,14 @@ static void qobject_output_type_int64(Visitor *v, const char *name, int64_t *obj, Error **errp) { QObjectOutputVisitor *qov = to_qov(v); - qobject_output_add(qov, name, qint_from_int(*obj)); + qobject_output_add(qov, name, qnum_from_int(*obj)); } static void qobject_output_type_uint64(Visitor *v, const char *name, uint64_t *obj, Error **errp) { - /* FIXME values larger than INT64_MAX become negative */ QObjectOutputVisitor *qov = to_qov(v); - qobject_output_add(qov, name, qint_from_int(*obj)); + qobject_output_add(qov, name, qnum_from_uint(*obj)); } static void qobject_output_type_bool(Visitor *v, const char *name, bool *obj, @@ -177,7 +176,7 @@ static void qobject_output_type_number(Visitor *v, const char *name, double *obj, Error **errp) { QObjectOutputVisitor *qov = to_qov(v); - qobject_output_add(qov, name, qfloat_from_double(*obj)); + qobject_output_add(qov, name, qnum_from_double(*obj)); } static void qobject_output_type_any(Visitor *v, const char *name, diff --git a/qapi/trace-events b/qapi/trace-events index 339cacf0ad..3b57abaa37 100644 --- a/qapi/trace-events +++ b/qapi/trace-events @@ -11,7 +11,7 @@ visit_next_list(void *v, void *tail, size_t size) "v=%p tail=%p size=%zu" visit_check_list(void *v) "v=%p" visit_end_list(void *v, void *obj) "v=%p obj=%p" -visit_start_alternate(void *v, const char *name, void *obj, size_t size, bool promote_int) "v=%p name=%s obj=%p size=%zu promote_int=%d" +visit_start_alternate(void *v, const char *name, void *obj, size_t size) "v=%p name=%s obj=%p size=%zu" visit_end_alternate(void *v, void *obj) "v=%p obj=%p" visit_optional(void *v, const char *name, bool *present) "v=%p name=%s present=%p" diff --git a/qga/commands.c b/qga/commands.c index 3333ed50b2..ff89e805cf 100644 --- a/qga/commands.c +++ b/qga/commands.c @@ -485,7 +485,7 @@ int ga_parse_whence(GuestFileWhence *whence, Error **errp) { /* Exploit the fact that we picked values to match QGA_SEEK_*. */ if (whence->type == QTYPE_QSTRING) { - whence->type = QTYPE_QINT; + whence->type = QTYPE_QNUM; whence->u.value = whence->u.name; } switch (whence->u.value) { diff --git a/qga/main.c b/qga/main.c index cc58d2b53d..405c1290f8 100644 --- a/qga/main.c +++ b/qga/main.c @@ -19,7 +19,6 @@ #endif #include "qapi/qmp/json-streamer.h" #include "qapi/qmp/json-parser.h" -#include "qapi/qmp/qint.h" #include "qapi/qmp/qjson.h" #include "qga/guest-agent-core.h" #include "qemu/module.h" diff --git a/qobject/Makefile.objs b/qobject/Makefile.objs index bed55084bb..fc8885c9a4 100644 --- a/qobject/Makefile.objs +++ b/qobject/Makefile.objs @@ -1,2 +1,2 @@ -util-obj-y = qnull.o qint.o qstring.o qdict.o qlist.o qfloat.o qbool.o +util-obj-y = qnull.o qnum.o qstring.o qdict.o qlist.o qbool.o util-obj-y += qjson.o qobject.o json-lexer.o json-streamer.o json-parser.o diff --git a/qobject/json-lexer.c b/qobject/json-lexer.c index af4a75e05b..980ba159d6 100644 --- a/qobject/json-lexer.c +++ b/qobject/json-lexer.c @@ -227,15 +227,18 @@ static const uint8_t json_lexer[][256] = { /* escape */ [IN_ESCAPE_LL] = { ['d'] = JSON_ESCAPE, + ['u'] = JSON_ESCAPE, }, [IN_ESCAPE_L] = { ['d'] = JSON_ESCAPE, ['l'] = IN_ESCAPE_LL, + ['u'] = JSON_ESCAPE, }, [IN_ESCAPE_I64] = { ['d'] = JSON_ESCAPE, + ['u'] = JSON_ESCAPE, }, [IN_ESCAPE_I6] = { @@ -251,6 +254,7 @@ static const uint8_t json_lexer[][256] = { ['i'] = JSON_ESCAPE, ['p'] = JSON_ESCAPE, ['s'] = JSON_ESCAPE, + ['u'] = JSON_ESCAPE, ['f'] = JSON_ESCAPE, ['l'] = IN_ESCAPE_L, ['I'] = IN_ESCAPE_I, diff --git a/qobject/json-parser.c b/qobject/json-parser.c index c18e48ab94..7a417f20cd 100644 --- a/qobject/json-parser.c +++ b/qobject/json-parser.c @@ -12,6 +12,7 @@ */ #include "qemu/osdep.h" +#include "qemu/cutils.h" #include "qapi/error.h" #include "qemu-common.h" #include "qapi/qmp/types.h" @@ -466,16 +467,23 @@ static QObject *parse_escape(JSONParserContext *ctxt, va_list *ap) } else if (!strcmp(token->str, "%i")) { return QOBJECT(qbool_from_bool(va_arg(*ap, int))); } else if (!strcmp(token->str, "%d")) { - return QOBJECT(qint_from_int(va_arg(*ap, int))); + return QOBJECT(qnum_from_int(va_arg(*ap, int))); } else if (!strcmp(token->str, "%ld")) { - return QOBJECT(qint_from_int(va_arg(*ap, long))); + return QOBJECT(qnum_from_int(va_arg(*ap, long))); } else if (!strcmp(token->str, "%lld") || !strcmp(token->str, "%I64d")) { - return QOBJECT(qint_from_int(va_arg(*ap, long long))); + return QOBJECT(qnum_from_int(va_arg(*ap, long long))); + } else if (!strcmp(token->str, "%u")) { + return QOBJECT(qnum_from_uint(va_arg(*ap, unsigned int))); + } else if (!strcmp(token->str, "%lu")) { + return QOBJECT(qnum_from_uint(va_arg(*ap, unsigned long))); + } else if (!strcmp(token->str, "%llu") || + !strcmp(token->str, "%I64u")) { + return QOBJECT(qnum_from_uint(va_arg(*ap, unsigned long long))); } else if (!strcmp(token->str, "%s")) { return QOBJECT(qstring_from_str(va_arg(*ap, const char *))); } else if (!strcmp(token->str, "%f")) { - return QOBJECT(qfloat_from_double(va_arg(*ap, double))); + return QOBJECT(qnum_from_double(va_arg(*ap, double))); } return NULL; } @@ -491,24 +499,34 @@ static QObject *parse_literal(JSONParserContext *ctxt) case JSON_STRING: return QOBJECT(qstring_from_escaped_str(ctxt, token)); case JSON_INTEGER: { - /* A possibility exists that this is a whole-valued float where the - * fractional part was left out due to being 0 (.0). It's not a big - * deal to treat these as ints in the parser, so long as users of the - * resulting QObject know to expect a QInt in place of a QFloat in - * cases like these. + /* + * Represent JSON_INTEGER as QNUM_I64 if possible, else as + * QNUM_U64, else as QNUM_DOUBLE. Note that qemu_strtoi64() + * and qemu_strtou64() fail with ERANGE when it's not + * possible. * - * However, in some cases these values will overflow/underflow a - * QInt/int64 container, thus we should assume these are to be handled - * as QFloats/doubles rather than silently changing their values. - * - * strtoll() indicates these instances by setting errno to ERANGE + * qnum_get_int() will then work for any signed 64-bit + * JSON_INTEGER, qnum_get_uint() for any unsigned 64-bit + * integer, and qnum_get_double() both for any JSON_INTEGER + * and any JSON_FLOAT (with precision loss for integers beyond + * 53 bits) */ + int ret; int64_t value; + uint64_t uvalue; + + ret = qemu_strtoi64(token->str, NULL, 10, &value); + if (!ret) { + return QOBJECT(qnum_from_int(value)); + } + assert(ret == -ERANGE); - errno = 0; /* strtoll doesn't set errno on success */ - value = strtoll(token->str, NULL, 10); - if (errno != ERANGE) { - return QOBJECT(qint_from_int(value)); + if (token->str[0] != '-') { + ret = qemu_strtou64(token->str, NULL, 10, &uvalue); + if (!ret) { + return QOBJECT(qnum_from_uint(uvalue)); + } + assert(ret == -ERANGE); } /* fall through to JSON_FLOAT */ } @@ -516,7 +534,7 @@ static QObject *parse_literal(JSONParserContext *ctxt) /* FIXME dependent on locale; a pervasive issue in QEMU */ /* FIXME our lexer matches RFC 7159 in forbidding Inf or NaN, * but those might be useful extensions beyond JSON */ - return QOBJECT(qfloat_from_double(strtod(token->str, NULL))); + return QOBJECT(qnum_from_double(strtod(token->str, NULL))); default: abort(); } diff --git a/qobject/qdict.c b/qobject/qdict.c index 88e2ecd658..576018e531 100644 --- a/qobject/qdict.c +++ b/qobject/qdict.c @@ -11,8 +11,7 @@ */ #include "qemu/osdep.h" -#include "qapi/qmp/qint.h" -#include "qapi/qmp/qfloat.h" +#include "qapi/qmp/qnum.h" #include "qapi/qmp/qdict.h" #include "qapi/qmp/qbool.h" #include "qapi/qmp/qstring.h" @@ -180,37 +179,26 @@ size_t qdict_size(const QDict *qdict) /** * qdict_get_double(): Get an number mapped by 'key' * - * This function assumes that 'key' exists and it stores a - * QFloat or QInt object. + * This function assumes that 'key' exists and it stores a QNum. * * Return number mapped by 'key'. */ double qdict_get_double(const QDict *qdict, const char *key) { - QObject *obj = qdict_get(qdict, key); - - assert(obj); - switch (qobject_type(obj)) { - case QTYPE_QFLOAT: - return qfloat_get_double(qobject_to_qfloat(obj)); - case QTYPE_QINT: - return qint_get_int(qobject_to_qint(obj)); - default: - abort(); - } + return qnum_get_double(qobject_to_qnum(qdict_get(qdict, key))); } /** * qdict_get_int(): Get an integer mapped by 'key' * * This function assumes that 'key' exists and it stores a - * QInt object. + * QNum representable as int. * * Return integer mapped by 'key'. */ int64_t qdict_get_int(const QDict *qdict, const char *key) { - return qint_get_int(qobject_to_qint(qdict_get(qdict, key))); + return qnum_get_int(qobject_to_qnum(qdict_get(qdict, key))); } /** @@ -259,16 +247,21 @@ const char *qdict_get_str(const QDict *qdict, const char *key) /** * qdict_get_try_int(): Try to get integer mapped by 'key' * - * Return integer mapped by 'key', if it is not present in - * the dictionary or if the stored object is not of QInt type - * 'def_value' will be returned. + * Return integer mapped by 'key', if it is not present in the + * dictionary or if the stored object is not a QNum representing an + * integer, 'def_value' will be returned. */ int64_t qdict_get_try_int(const QDict *qdict, const char *key, int64_t def_value) { - QInt *qint = qobject_to_qint(qdict_get(qdict, key)); + QNum *qnum = qobject_to_qnum(qdict_get(qdict, key)); + int64_t val; + + if (!qnum || !qnum_get_try_int(qnum, &val)) { + return def_value; + } - return qint ? qint_get_int(qint) : def_value; + return val; } /** diff --git a/qobject/qfloat.c b/qobject/qfloat.c deleted file mode 100644 index d5da847701..0000000000 --- a/qobject/qfloat.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * QFloat Module - * - * Copyright IBM, Corp. 2009 - * - * Authors: - * Anthony Liguori <aliguori@us.ibm.com> - * - * 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/osdep.h" -#include "qapi/qmp/qfloat.h" -#include "qapi/qmp/qobject.h" -#include "qemu-common.h" - -/** - * qfloat_from_int(): Create a new QFloat from a float - * - * Return strong reference. - */ -QFloat *qfloat_from_double(double value) -{ - QFloat *qf; - - qf = g_malloc(sizeof(*qf)); - qobject_init(QOBJECT(qf), QTYPE_QFLOAT); - qf->value = value; - - return qf; -} - -/** - * qfloat_get_double(): Get the stored float - */ -double qfloat_get_double(const QFloat *qf) -{ - return qf->value; -} - -/** - * qobject_to_qfloat(): Convert a QObject into a QFloat - */ -QFloat *qobject_to_qfloat(const QObject *obj) -{ - if (!obj || qobject_type(obj) != QTYPE_QFLOAT) { - return NULL; - } - return container_of(obj, QFloat, base); -} - -/** - * qfloat_destroy_obj(): Free all memory allocated by a - * QFloat object - */ -void qfloat_destroy_obj(QObject *obj) -{ - assert(obj != NULL); - g_free(qobject_to_qfloat(obj)); -} diff --git a/qobject/qint.c b/qobject/qint.c deleted file mode 100644 index d7d1b3021f..0000000000 --- a/qobject/qint.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * QInt Module - * - * Copyright (C) 2009 Red Hat Inc. - * - * Authors: - * Luiz Capitulino <lcapitulino@redhat.com> - * - * 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/osdep.h" -#include "qapi/qmp/qint.h" -#include "qapi/qmp/qobject.h" -#include "qemu-common.h" - -/** - * qint_from_int(): Create a new QInt from an int64_t - * - * Return strong reference. - */ -QInt *qint_from_int(int64_t value) -{ - QInt *qi; - - qi = g_malloc(sizeof(*qi)); - qobject_init(QOBJECT(qi), QTYPE_QINT); - qi->value = value; - - return qi; -} - -/** - * qint_get_int(): Get the stored integer - */ -int64_t qint_get_int(const QInt *qi) -{ - return qi->value; -} - -/** - * qobject_to_qint(): Convert a QObject into a QInt - */ -QInt *qobject_to_qint(const QObject *obj) -{ - if (!obj || qobject_type(obj) != QTYPE_QINT) { - return NULL; - } - return container_of(obj, QInt, base); -} - -/** - * qint_destroy_obj(): Free all memory allocated by a - * QInt object - */ -void qint_destroy_obj(QObject *obj) -{ - assert(obj != NULL); - g_free(qobject_to_qint(obj)); -} diff --git a/qobject/qjson.c b/qobject/qjson.c index b2f3bfec53..2e0930884e 100644 --- a/qobject/qjson.c +++ b/qobject/qjson.c @@ -132,12 +132,11 @@ static void to_json(const QObject *obj, QString *str, int pretty, int indent) case QTYPE_QNULL: qstring_append(str, "null"); break; - case QTYPE_QINT: { - QInt *val = qobject_to_qint(obj); - char buffer[1024]; - - snprintf(buffer, sizeof(buffer), "%" PRId64, qint_get_int(val)); + case QTYPE_QNUM: { + QNum *val = qobject_to_qnum(obj); + char *buffer = qnum_to_string(val); qstring_append(str, buffer); + g_free(buffer); break; } case QTYPE_QSTRING: { @@ -234,34 +233,6 @@ static void to_json(const QObject *obj, QString *str, int pretty, int indent) qstring_append(str, "]"); break; } - case QTYPE_QFLOAT: { - QFloat *val = qobject_to_qfloat(obj); - char buffer[1024]; - int len; - - /* FIXME: snprintf() is locale dependent; but JSON requires - * numbers to be formatted as if in the C locale. Dependence - * on C locale is a pervasive issue in QEMU. */ - /* FIXME: This risks printing Inf or NaN, which are not valid - * JSON values. */ - /* FIXME: the default precision of 6 for %f often causes - * rounding errors; we should be using DBL_DECIMAL_DIG (17), - * and only rounding to a shorter number if the result would - * still produce the same floating point value. */ - len = snprintf(buffer, sizeof(buffer), "%f", qfloat_get_double(val)); - while (len > 0 && buffer[len - 1] == '0') { - len--; - } - - if (len && buffer[len - 1] == '.') { - buffer[len - 1] = 0; - } else { - buffer[len] = 0; - } - - qstring_append(str, buffer); - break; - } case QTYPE_QBOOL: { QBool *val = qobject_to_qbool(obj); diff --git a/qobject/qnum.c b/qobject/qnum.c new file mode 100644 index 0000000000..476e81c93b --- /dev/null +++ b/qobject/qnum.c @@ -0,0 +1,223 @@ +/* + * QNum Module + * + * Copyright (C) 2009 Red Hat Inc. + * + * Authors: + * Luiz Capitulino <lcapitulino@redhat.com> + * Anthony Liguori <aliguori@us.ibm.com> + * Marc-André Lureau <marcandre.lureau@redhat.com> + * + * 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/osdep.h" +#include "qapi/error.h" +#include "qapi/qmp/qnum.h" +#include "qapi/qmp/qobject.h" +#include "qemu-common.h" + +/** + * qnum_from_int(): Create a new QNum from an int64_t + * + * Return strong reference. + */ +QNum *qnum_from_int(int64_t value) +{ + QNum *qn = g_new(QNum, 1); + + qobject_init(QOBJECT(qn), QTYPE_QNUM); + qn->kind = QNUM_I64; + qn->u.i64 = value; + + return qn; +} + +/** + * qnum_from_uint(): Create a new QNum from an uint64_t + * + * Return strong reference. + */ +QNum *qnum_from_uint(uint64_t value) +{ + QNum *qn = g_new(QNum, 1); + + qobject_init(QOBJECT(qn), QTYPE_QNUM); + qn->kind = QNUM_U64; + qn->u.u64 = value; + + return qn; +} + +/** + * qnum_from_double(): Create a new QNum from a double + * + * Return strong reference. + */ +QNum *qnum_from_double(double value) +{ + QNum *qn = g_new(QNum, 1); + + qobject_init(QOBJECT(qn), QTYPE_QNUM); + qn->kind = QNUM_DOUBLE; + qn->u.dbl = value; + + return qn; +} + +/** + * qnum_get_try_int(): Get an integer representation of the number + * + * Return true on success. + */ +bool qnum_get_try_int(const QNum *qn, int64_t *val) +{ + switch (qn->kind) { + case QNUM_I64: + *val = qn->u.i64; + return true; + case QNUM_U64: + if (qn->u.u64 > INT64_MAX) { + return false; + } + *val = qn->u.u64; + return true; + case QNUM_DOUBLE: + return false; + } + + assert(0); + return false; +} + +/** + * qnum_get_int(): Get an integer representation of the number + * + * assert() on failure. + */ +int64_t qnum_get_int(const QNum *qn) +{ + int64_t val; + bool success = qnum_get_try_int(qn, &val); + assert(success); + return val; +} + +/** + * qnum_get_uint(): Get an unsigned integer from the number + * + * Return true on success. + */ +bool qnum_get_try_uint(const QNum *qn, uint64_t *val) +{ + switch (qn->kind) { + case QNUM_I64: + if (qn->u.i64 < 0) { + return false; + } + *val = qn->u.i64; + return true; + case QNUM_U64: + *val = qn->u.u64; + return true; + case QNUM_DOUBLE: + return false; + } + + assert(0); + return false; +} + +/** + * qnum_get_uint(): Get an unsigned integer from the number + * + * assert() on failure. + */ +uint64_t qnum_get_uint(const QNum *qn) +{ + uint64_t val; + bool success = qnum_get_try_uint(qn, &val); + assert(success); + return val; +} + +/** + * qnum_get_double(): Get a float representation of the number + * + * qnum_get_double() loses precision for integers beyond 53 bits. + */ +double qnum_get_double(QNum *qn) +{ + switch (qn->kind) { + case QNUM_I64: + return qn->u.i64; + case QNUM_U64: + return qn->u.u64; + case QNUM_DOUBLE: + return qn->u.dbl; + } + + assert(0); + return 0.0; +} + +char *qnum_to_string(QNum *qn) +{ + char *buffer; + int len; + + switch (qn->kind) { + case QNUM_I64: + return g_strdup_printf("%" PRId64, qn->u.i64); + case QNUM_U64: + return g_strdup_printf("%" PRIu64, qn->u.u64); + case QNUM_DOUBLE: + /* FIXME: snprintf() is locale dependent; but JSON requires + * numbers to be formatted as if in the C locale. Dependence + * on C locale is a pervasive issue in QEMU. */ + /* FIXME: This risks printing Inf or NaN, which are not valid + * JSON values. */ + /* FIXME: the default precision of 6 for %f often causes + * rounding errors; we should be using DBL_DECIMAL_DIG (17), + * and only rounding to a shorter number if the result would + * still produce the same floating point value. */ + buffer = g_strdup_printf("%f" , qn->u.dbl); + len = strlen(buffer); + while (len > 0 && buffer[len - 1] == '0') { + len--; + } + + if (len && buffer[len - 1] == '.') { + buffer[len - 1] = 0; + } else { + buffer[len] = 0; + } + + return buffer; + } + + assert(0); + return NULL; +} + +/** + * qobject_to_qnum(): Convert a QObject into a QNum + */ +QNum *qobject_to_qnum(const QObject *obj) +{ + if (!obj || qobject_type(obj) != QTYPE_QNUM) { + return NULL; + } + return container_of(obj, QNum, base); +} + +/** + * qnum_destroy_obj(): Free all memory allocated by a + * QNum object + */ +void qnum_destroy_obj(QObject *obj) +{ + assert(obj != NULL); + g_free(qobject_to_qnum(obj)); +} diff --git a/qobject/qobject.c b/qobject/qobject.c index fe4fa10989..b0cafb66f1 100644 --- a/qobject/qobject.c +++ b/qobject/qobject.c @@ -14,11 +14,10 @@ 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_QNUM] = qnum_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, }; diff --git a/qom/object.c b/qom/object.c index eb4bc924ff..5f6fdfa6e6 100644 --- a/qom/object.c +++ b/qom/object.c @@ -27,7 +27,6 @@ #include "qom/qom-qobject.h" #include "qapi/qmp/qobject.h" #include "qapi/qmp/qbool.h" -#include "qapi/qmp/qint.h" #include "qapi/qmp/qstring.h" #define MAX_INTERFACES 32 @@ -1122,7 +1121,7 @@ char *object_property_get_str(Object *obj, const char *name, retval = g_strdup(qstring_get_str(qstring)); } - QDECREF(qstring); + qobject_decref(ret); return retval; } @@ -1183,38 +1182,66 @@ bool object_property_get_bool(Object *obj, const char *name, retval = qbool_get_bool(qbool); } - QDECREF(qbool); + qobject_decref(ret); return retval; } void object_property_set_int(Object *obj, int64_t value, const char *name, Error **errp) { - QInt *qint = qint_from_int(value); - object_property_set_qobject(obj, QOBJECT(qint), name, errp); + QNum *qnum = qnum_from_int(value); + object_property_set_qobject(obj, QOBJECT(qnum), name, errp); - QDECREF(qint); + QDECREF(qnum); } int64_t object_property_get_int(Object *obj, const char *name, Error **errp) { QObject *ret = object_property_get_qobject(obj, name, errp); - QInt *qint; + QNum *qnum; int64_t retval; if (!ret) { return -1; } - qint = qobject_to_qint(ret); - if (!qint) { + + qnum = qobject_to_qnum(ret); + if (!qnum || !qnum_get_try_int(qnum, &retval)) { error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "int"); retval = -1; - } else { - retval = qint_get_int(qint); } - QDECREF(qint); + qobject_decref(ret); + return retval; +} + +void object_property_set_uint(Object *obj, uint64_t value, + const char *name, Error **errp) +{ + QNum *qnum = qnum_from_uint(value); + + object_property_set_qobject(obj, QOBJECT(qnum), name, errp); + QDECREF(qnum); +} + +uint64_t object_property_get_uint(Object *obj, const char *name, + Error **errp) +{ + QObject *ret = object_property_get_qobject(obj, name, errp); + QNum *qnum; + uint64_t retval; + + if (!ret) { + return 0; + } + qnum = qobject_to_qnum(ret); + if (!qnum || !qnum_get_try_uint(qnum, &retval)) { + error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "uint"); + retval = 0; + } + + qobject_decref(ret); return retval; } diff --git a/scripts/coccinelle/qobject.cocci b/scripts/coccinelle/qobject.cocci index 97703a438b..c3253deb1b 100644 --- a/scripts/coccinelle/qobject.cocci +++ b/scripts/coccinelle/qobject.cocci @@ -6,7 +6,7 @@ expression Obj, Key, E; - qdict_put_obj(Obj, Key, QOBJECT(E)); + qdict_put(Obj, Key, E); | -- qdict_put(Obj, Key, qint_from_int(E)); +- qdict_put(Obj, Key, qnum_from_int(E)); + qdict_put_int(Obj, Key, E); | - qdict_put(Obj, Key, qbool_from_bool(E)); @@ -24,7 +24,7 @@ expression Obj, E; - qlist_append_obj(Obj, QOBJECT(E)); + qlist_append(Obj, E); | -- qlist_append(Obj, qint_from_int(E)); +- qlist_append(Obj, qnum_from_int(E)); + qlist_append_int(Obj, E); | - qlist_append(Obj, qbool_from_bool(E)); diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py index 5737aefa05..bd0b742236 100644 --- a/scripts/qapi-visit.py +++ b/scripts/qapi-visit.py @@ -161,20 +161,14 @@ void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s *obj, Error def gen_visit_alternate(name, variants): - promote_int = 'true' - ret = '' - 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, const char *name, %(c_name)s **obj, Error **errp) { Error *err = NULL; visit_start_alternate(v, name, (GenericAlternate **)obj, sizeof(**obj), - %(promote_int)s, &err); + &err); if (err) { goto out; } @@ -183,7 +177,7 @@ void visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error } switch ((*obj)->type) { ''', - c_name=c_name(name), promote_int=promote_int) + c_name=c_name(name)) for var in variants.variants: ret += mcgen(''' diff --git a/scripts/qapi.py b/scripts/qapi.py index b7a25e4759..0de809f56b 100644 --- a/scripts/qapi.py +++ b/scripts/qapi.py @@ -21,18 +21,18 @@ from ordereddict import OrderedDict builtin_types = { 'str': 'QTYPE_QSTRING', - 'int': 'QTYPE_QINT', - 'number': 'QTYPE_QFLOAT', + 'int': 'QTYPE_QNUM', + 'number': 'QTYPE_QNUM', 'bool': 'QTYPE_QBOOL', - 'int8': 'QTYPE_QINT', - 'int16': 'QTYPE_QINT', - 'int32': 'QTYPE_QINT', - 'int64': 'QTYPE_QINT', - 'uint8': 'QTYPE_QINT', - 'uint16': 'QTYPE_QINT', - 'uint32': 'QTYPE_QINT', - 'uint64': 'QTYPE_QINT', - 'size': 'QTYPE_QINT', + 'int8': 'QTYPE_QNUM', + 'int16': 'QTYPE_QNUM', + 'int32': 'QTYPE_QNUM', + 'int64': 'QTYPE_QNUM', + 'uint8': 'QTYPE_QNUM', + 'uint16': 'QTYPE_QNUM', + 'uint32': 'QTYPE_QNUM', + 'uint64': 'QTYPE_QNUM', + 'size': 'QTYPE_QNUM', 'any': None, # any QType possible, actually 'QType': 'QTYPE_QSTRING', } @@ -820,11 +820,9 @@ def check_alternate(expr, info): if v in ['on', 'off']: conflicting.add('QTYPE_QBOOL') if re.match(r'[-+0-9.]', v): # lazy, could be tightened - conflicting.add('QTYPE_QINT') - conflicting.add('QTYPE_QFLOAT') + conflicting.add('QTYPE_QNUM') else: - conflicting.add('QTYPE_QINT') - conflicting.add('QTYPE_QFLOAT') + conflicting.add('QTYPE_QNUM') conflicting.add('QTYPE_QBOOL') if conflicting & set(types_seen): raise QAPISemError(info, "Alternate '%s' member '%s' can't " @@ -1059,8 +1057,8 @@ class QAPISchemaType(QAPISchemaEntity): def alternate_qtype(self): json2qtype = { 'string': 'QTYPE_QSTRING', - 'number': 'QTYPE_QFLOAT', - 'int': 'QTYPE_QINT', + 'number': 'QTYPE_QNUM', + 'int': 'QTYPE_QNUM', 'boolean': 'QTYPE_QBOOL', 'object': 'QTYPE_QDICT' } @@ -1522,9 +1520,9 @@ class QAPISchema(object): self.the_empty_object_type = QAPISchemaObjectType( 'q_empty', None, None, None, [], None) self._def_entity(self.the_empty_object_type) - qtype_values = self._make_enum_members(['none', 'qnull', 'qint', + qtype_values = self._make_enum_members(['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', - 'qfloat', 'qbool']) + 'qbool']) self._def_entity(QAPISchemaEnumType('QType', None, None, qtype_values, 'QTYPE')) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index b2b1d20cee..642519a7fc 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -29,11 +29,7 @@ #include "qemu/option.h" #include "qemu/config-file.h" #include "qapi/qmp/qerror.h" -#include "qapi/qmp/qstring.h" -#include "qapi/qmp/qdict.h" -#include "qapi/qmp/qbool.h" -#include "qapi/qmp/qint.h" -#include "qapi/qmp/qfloat.h" +#include "qapi/qmp/types.h" #include "qapi-types.h" #include "qapi-visit.h" @@ -2328,8 +2324,8 @@ static void x86_cpu_load_def(X86CPU *cpu, X86CPUDefinition *def, Error **errp) */ /* CPU models only set _minimum_ values for level/xlevel: */ - object_property_set_int(OBJECT(cpu), def->level, "min-level", errp); - object_property_set_int(OBJECT(cpu), def->xlevel, "min-xlevel", errp); + object_property_set_uint(OBJECT(cpu), def->level, "min-level", errp); + object_property_set_uint(OBJECT(cpu), def->xlevel, "min-xlevel", errp); object_property_set_int(OBJECT(cpu), def->family, "family", errp); object_property_set_int(OBJECT(cpu), def->model, "model", errp); diff --git a/tests/.gitignore b/tests/.gitignore index 40c2e3e757..8e01b004f1 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -1,7 +1,6 @@ atomic_add-bench check-qdict -check-qfloat -check-qint +check-qnum check-qjson check-qlist check-qnull diff --git a/tests/Makefile.include b/tests/Makefile.include index 77da9b7f4b..ae889cae02 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -10,10 +10,8 @@ check-unit-y = tests/check-qdict$(EXESUF) gcov-files-check-qdict-y = qobject/qdict.c check-unit-y += tests/test-char$(EXESUF) gcov-files-check-qdict-y = chardev/char.c -check-unit-y += tests/check-qfloat$(EXESUF) -gcov-files-check-qfloat-y = qobject/qfloat.c -check-unit-y += tests/check-qint$(EXESUF) -gcov-files-check-qint-y = qobject/qint.c +check-unit-y += tests/check-qnum$(EXESUF) +gcov-files-check-qnum-y = qobject/qnum.c check-unit-y += tests/check-qstring$(EXESUF) gcov-files-check-qstring-y = qobject/qstring.c check-unit-y += tests/check-qlist$(EXESUF) @@ -508,8 +506,8 @@ GENERATED_FILES += tests/test-qapi-types.h tests/test-qapi-visit.h \ tests/test-qmp-commands.h tests/test-qapi-event.h \ tests/test-qmp-introspect.h -test-obj-y = tests/check-qint.o tests/check-qstring.o tests/check-qdict.o \ - tests/check-qlist.o tests/check-qfloat.o tests/check-qnull.o \ +test-obj-y = tests/check-qnum.o tests/check-qstring.o tests/check-qdict.o \ + tests/check-qlist.o tests/check-qnull.o \ tests/check-qjson.o \ tests/test-coroutine.o tests/test-string-output-visitor.o \ tests/test-string-input-visitor.o tests/test-qobject-output-visitor.o \ @@ -537,11 +535,10 @@ test-crypto-obj-y = $(crypto-obj-y) $(test-qom-obj-y) test-io-obj-y = $(io-obj-y) $(test-crypto-obj-y) test-block-obj-y = $(block-obj-y) $(test-io-obj-y) tests/iothread.o -tests/check-qint$(EXESUF): tests/check-qint.o $(test-util-obj-y) +tests/check-qnum$(EXESUF): tests/check-qnum.o $(test-util-obj-y) tests/check-qstring$(EXESUF): tests/check-qstring.o $(test-util-obj-y) tests/check-qdict$(EXESUF): tests/check-qdict.o $(test-util-obj-y) tests/check-qlist$(EXESUF): tests/check-qlist.o $(test-util-obj-y) -tests/check-qfloat$(EXESUF): tests/check-qfloat.o $(test-util-obj-y) tests/check-qnull$(EXESUF): tests/check-qnull.o $(test-util-obj-y) tests/check-qjson$(EXESUF): tests/check-qjson.o $(test-util-obj-y) tests/check-qom-interface$(EXESUF): tests/check-qom-interface.o $(test-qom-obj-y) diff --git a/tests/check-qdict.c b/tests/check-qdict.c index be8d81f07b..35405778cc 100644 --- a/tests/check-qdict.c +++ b/tests/check-qdict.c @@ -11,7 +11,6 @@ */ #include "qemu/osdep.h" -#include "qapi/qmp/qint.h" #include "qapi/qmp/qdict.h" #include "qapi/qmp/qstring.h" #include "qapi/error.h" @@ -33,13 +32,12 @@ static void qdict_new_test(void) g_assert(qdict->base.refcnt == 1); g_assert(qobject_type(QOBJECT(qdict)) == QTYPE_QDICT); - // destroy doesn't exit yet - g_free(qdict); + QDECREF(qdict); } static void qdict_put_obj_test(void) { - QInt *qi; + QNum *qn; QDict *qdict; QDictEntry *ent; const int num = 42; @@ -51,14 +49,10 @@ static void qdict_put_obj_test(void) g_assert(qdict_size(qdict) == 1); ent = QLIST_FIRST(&qdict->table[12345 % QDICT_BUCKET_MAX]); - qi = qobject_to_qint(ent->value); - g_assert(qint_get_int(qi) == num); - - // destroy doesn't exit yet - QDECREF(qi); - g_free(ent->key); - g_free(ent); - g_free(qdict); + qn = qobject_to_qnum(ent->value); + g_assert_cmpint(qnum_get_int(qn), ==, num); + + QDECREF(qdict); } static void qdict_destroy_simple_test(void) @@ -74,7 +68,7 @@ static void qdict_destroy_simple_test(void) static void qdict_get_test(void) { - QInt *qi; + QNum *qn; QObject *obj; const int value = -42; const char *key = "test"; @@ -85,8 +79,8 @@ static void qdict_get_test(void) obj = qdict_get(tests_dict, key); g_assert(obj != NULL); - qi = qobject_to_qint(obj); - g_assert(qint_get_int(qi) == value); + qn = qobject_to_qnum(obj); + g_assert_cmpint(qnum_get_int(qn), ==, value); QDECREF(tests_dict); } @@ -114,10 +108,17 @@ static void qdict_get_try_int_test(void) QDict *tests_dict = qdict_new(); qdict_put_int(tests_dict, key, value); + qdict_put_str(tests_dict, "string", "test"); ret = qdict_get_try_int(tests_dict, key, 0); g_assert(ret == value); + ret = qdict_get_try_int(tests_dict, "missing", -42); + g_assert_cmpuint(ret, ==, -42); + + ret = qdict_get_try_int(tests_dict, "string", -42); + g_assert_cmpuint(ret, ==, -42); + QDECREF(tests_dict); } @@ -329,7 +330,7 @@ static void qdict_array_split_test(void) { QDict *test_dict = qdict_new(); QDict *dict1, *dict2; - QInt *int1; + QNum *int1; QList *test_list; /* @@ -380,7 +381,7 @@ static void qdict_array_split_test(void) dict1 = qobject_to_qdict(qlist_pop(test_list)); dict2 = qobject_to_qdict(qlist_pop(test_list)); - int1 = qobject_to_qint(qlist_pop(test_list)); + int1 = qobject_to_qnum(qlist_pop(test_list)); g_assert(dict1); g_assert(dict2); @@ -402,7 +403,7 @@ static void qdict_array_split_test(void) QDECREF(dict2); - g_assert(qint_get_int(int1) == 66); + g_assert_cmpint(qnum_get_int(int1), ==, 66); QDECREF(int1); @@ -447,14 +448,14 @@ static void qdict_array_split_test(void) qdict_array_split(test_dict, &test_list); - int1 = qobject_to_qint(qlist_pop(test_list)); + int1 = qobject_to_qnum(qlist_pop(test_list)); g_assert(int1); g_assert(qlist_empty(test_list)); QDECREF(test_list); - g_assert(qint_get_int(int1) == 42); + g_assert_cmpint(qnum_get_int(int1), ==, 42); QDECREF(int1); diff --git a/tests/check-qfloat.c b/tests/check-qfloat.c deleted file mode 100644 index 1da2cdae08..0000000000 --- a/tests/check-qfloat.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * QFloat unit-tests. - * - * Copyright IBM, Corp. 2009 - * - * Authors: - * Anthony Liguori <aliguori@us.ibm.com> - * - * 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/osdep.h" - -#include "qapi/qmp/qfloat.h" -#include "qemu-common.h" - -/* - * Public Interface test-cases - * - * (with some violations to access 'private' data) - */ - -static void qfloat_from_double_test(void) -{ - QFloat *qf; - const double value = -42.23423; - - qf = qfloat_from_double(value); - g_assert(qf != NULL); - g_assert(qf->value == value); - g_assert(qf->base.refcnt == 1); - g_assert(qobject_type(QOBJECT(qf)) == QTYPE_QFLOAT); - - // destroy doesn't exit yet - g_free(qf); -} - -static void qfloat_destroy_test(void) -{ - QFloat *qf = qfloat_from_double(0.0); - QDECREF(qf); -} - -int main(int argc, char **argv) -{ - g_test_init(&argc, &argv, NULL); - - g_test_add_func("/public/from_double", qfloat_from_double_test); - g_test_add_func("/public/destroy", qfloat_destroy_test); - - return g_test_run(); -} diff --git a/tests/check-qint.c b/tests/check-qint.c deleted file mode 100644 index b6e4555115..0000000000 --- a/tests/check-qint.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * QInt unit-tests. - * - * Copyright (C) 2009 Red Hat Inc. - * - * Authors: - * Luiz Capitulino <lcapitulino@redhat.com> - * - * 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/osdep.h" - -#include "qapi/qmp/qint.h" -#include "qemu-common.h" - -/* - * Public Interface test-cases - * - * (with some violations to access 'private' data) - */ - -static void qint_from_int_test(void) -{ - QInt *qi; - const int value = -42; - - qi = qint_from_int(value); - g_assert(qi != NULL); - g_assert(qi->value == value); - g_assert(qi->base.refcnt == 1); - g_assert(qobject_type(QOBJECT(qi)) == QTYPE_QINT); - - // destroy doesn't exit yet - g_free(qi); -} - -static void qint_destroy_test(void) -{ - QInt *qi = qint_from_int(0); - QDECREF(qi); -} - -static void qint_from_int64_test(void) -{ - QInt *qi; - const int64_t value = 0x1234567890abcdefLL; - - qi = qint_from_int(value); - g_assert((int64_t) qi->value == value); - - QDECREF(qi); -} - -static void qint_get_int_test(void) -{ - QInt *qi; - const int value = 123456; - - qi = qint_from_int(value); - g_assert(qint_get_int(qi) == value); - - QDECREF(qi); -} - -static void qobject_to_qint_test(void) -{ - QInt *qi; - - qi = qint_from_int(0); - g_assert(qobject_to_qint(QOBJECT(qi)) == qi); - - QDECREF(qi); -} - -int main(int argc, char **argv) -{ - g_test_init(&argc, &argv, NULL); - - g_test_add_func("/public/from_int", qint_from_int_test); - g_test_add_func("/public/destroy", qint_destroy_test); - g_test_add_func("/public/from_int64", qint_from_int64_test); - g_test_add_func("/public/get_int", qint_get_int_test); - g_test_add_func("/public/to_qint", qobject_to_qint_test); - - return g_test_run(); -} diff --git a/tests/check-qjson.c b/tests/check-qjson.c index 963dd46f07..53f2275b9b 100644 --- a/tests/check-qjson.c +++ b/tests/check-qjson.c @@ -886,24 +886,69 @@ static void simple_number(void) }; for (i = 0; test_cases[i].encoded; i++) { - QInt *qint; + QNum *qnum; + int64_t val; - qint = qobject_to_qint(qobject_from_json(test_cases[i].encoded, + qnum = qobject_to_qnum(qobject_from_json(test_cases[i].encoded, &error_abort)); - g_assert(qint); - g_assert(qint_get_int(qint) == test_cases[i].decoded); + g_assert(qnum); + g_assert(qnum_get_try_int(qnum, &val)); + g_assert_cmpint(val, ==, test_cases[i].decoded); if (test_cases[i].skip == 0) { QString *str; - str = qobject_to_json(QOBJECT(qint)); + str = qobject_to_json(QOBJECT(qnum)); g_assert(strcmp(qstring_get_str(str), test_cases[i].encoded) == 0); QDECREF(str); } - QDECREF(qint); + QDECREF(qnum); } } +static void large_number(void) +{ + const char *maxu64 = "18446744073709551615"; /* 2^64-1 */ + const char *gtu64 = "18446744073709551616"; /* 2^64 */ + const char *lti64 = "-9223372036854775809"; /* -2^63 - 1 */ + QNum *qnum; + QString *str; + uint64_t val; + int64_t ival; + + qnum = qobject_to_qnum(qobject_from_json(maxu64, &error_abort)); + g_assert(qnum); + g_assert_cmpuint(qnum_get_uint(qnum), ==, 18446744073709551615U); + g_assert(!qnum_get_try_int(qnum, &ival)); + + str = qobject_to_json(QOBJECT(qnum)); + g_assert_cmpstr(qstring_get_str(str), ==, maxu64); + QDECREF(str); + QDECREF(qnum); + + qnum = qobject_to_qnum(qobject_from_json(gtu64, &error_abort)); + g_assert(qnum); + g_assert_cmpfloat(qnum_get_double(qnum), ==, 18446744073709552e3); + g_assert(!qnum_get_try_uint(qnum, &val)); + g_assert(!qnum_get_try_int(qnum, &ival)); + + str = qobject_to_json(QOBJECT(qnum)); + g_assert_cmpstr(qstring_get_str(str), ==, gtu64); + QDECREF(str); + QDECREF(qnum); + + qnum = qobject_to_qnum(qobject_from_json(lti64, &error_abort)); + g_assert(qnum); + g_assert_cmpfloat(qnum_get_double(qnum), ==, -92233720368547758e2); + g_assert(!qnum_get_try_uint(qnum, &val)); + g_assert(!qnum_get_try_int(qnum, &ival)); + + str = qobject_to_json(QOBJECT(qnum)); + g_assert_cmpstr(qstring_get_str(str), ==, "-9223372036854775808"); + QDECREF(str); + QDECREF(qnum); +} + static void float_number(void) { int i; @@ -921,12 +966,12 @@ static void float_number(void) for (i = 0; test_cases[i].encoded; i++) { QObject *obj; - QFloat *qfloat; + QNum *qnum; obj = qobject_from_json(test_cases[i].encoded, &error_abort); - qfloat = qobject_to_qfloat(obj); - g_assert(qfloat); - g_assert(qfloat_get_double(qfloat) == test_cases[i].decoded); + qnum = qobject_to_qnum(obj); + g_assert(qnum); + g_assert(qnum_get_double(qnum) == test_cases[i].decoded); if (test_cases[i].skip == 0) { QString *str; @@ -936,29 +981,31 @@ static void float_number(void) QDECREF(str); } - QDECREF(qfloat); + QDECREF(qnum); } } static void vararg_number(void) { - QInt *qint; - QFloat *qfloat; + QNum *qnum; int value = 0x2342; long long value_ll = 0x2342342343LL; double valuef = 2.323423423; + int64_t val; - qint = qobject_to_qint(qobject_from_jsonf("%d", value)); - g_assert(qint_get_int(qint) == value); - QDECREF(qint); + qnum = qobject_to_qnum(qobject_from_jsonf("%d", value)); + g_assert(qnum_get_try_int(qnum, &val)); + g_assert_cmpint(val, ==, value); + QDECREF(qnum); - qint = qobject_to_qint(qobject_from_jsonf("%lld", value_ll)); - g_assert(qint_get_int(qint) == value_ll); - QDECREF(qint); + qnum = qobject_to_qnum(qobject_from_jsonf("%lld", value_ll)); + g_assert(qnum_get_try_int(qnum, &val)); + g_assert_cmpint(val, ==, value_ll); + QDECREF(qnum); - qfloat = qobject_to_qfloat(qobject_from_jsonf("%f", valuef)); - g_assert(qfloat_get_double(qfloat) == valuef); - QDECREF(qfloat); + qnum = qobject_to_qnum(qobject_from_jsonf("%f", valuef)); + g_assert(qnum_get_double(qnum) == valuef); + QDECREF(qnum); } static void keyword_literal(void) @@ -1019,7 +1066,7 @@ struct LiteralQObject { int type; union { - int64_t qint; + int64_t qnum; const char *qstr; LiteralQDictEntry *qdict; LiteralQObject *qlist; @@ -1032,7 +1079,7 @@ struct LiteralQDictEntry LiteralQObject value; }; -#define QLIT_QINT(val) (LiteralQObject){.type = QTYPE_QINT, .value.qint = (val)} +#define QLIT_QNUM(val) (LiteralQObject){.type = QTYPE_QNUM, .value.qnum = (val)} #define QLIT_QSTR(val) (LiteralQObject){.type = QTYPE_QSTRING, .value.qstr = (val)} #define QLIT_QDICT(val) (LiteralQObject){.type = QTYPE_QDICT, .value.qdict = (val)} #define QLIT_QLIST(val) (LiteralQObject){.type = QTYPE_QLIST, .value.qlist = (val)} @@ -1064,13 +1111,16 @@ static void compare_helper(QObject *obj, void *opaque) static int compare_litqobj_to_qobj(LiteralQObject *lhs, QObject *rhs) { + int64_t val; + if (!rhs || lhs->type != qobject_type(rhs)) { return 0; } switch (lhs->type) { - case QTYPE_QINT: - return lhs->value.qint == qint_get_int(qobject_to_qint(rhs)); + case QTYPE_QNUM: + g_assert(qnum_get_try_int(qobject_to_qnum(rhs), &val)); + return lhs->value.qnum == val; case QTYPE_QSTRING: return (strcmp(lhs->value.qstr, qstring_get_str(qobject_to_qstring(rhs))) == 0); case QTYPE_QDICT: { @@ -1114,7 +1164,7 @@ static void simple_dict(void) { .encoded = "{\"foo\": 42, \"bar\": \"hello world\"}", .decoded = QLIT_QDICT(((LiteralQDictEntry[]){ - { "foo", QLIT_QINT(42) }, + { "foo", QLIT_QNUM(42) }, { "bar", QLIT_QSTR("hello world") }, { } })), @@ -1126,7 +1176,7 @@ static void simple_dict(void) }, { .encoded = "{\"foo\": 43}", .decoded = QLIT_QDICT(((LiteralQDictEntry[]){ - { "foo", QLIT_QINT(43) }, + { "foo", QLIT_QNUM(43) }, { } })), }, @@ -1212,15 +1262,15 @@ static void simple_list(void) { .encoded = "[43,42]", .decoded = QLIT_QLIST(((LiteralQObject[]){ - QLIT_QINT(43), - QLIT_QINT(42), + QLIT_QNUM(43), + QLIT_QNUM(42), { } })), }, { .encoded = "[43]", .decoded = QLIT_QLIST(((LiteralQObject[]){ - QLIT_QINT(43), + QLIT_QNUM(43), { } })), }, @@ -1269,35 +1319,35 @@ static void simple_whitespace(void) { .encoded = " [ 43 , 42 ]", .decoded = QLIT_QLIST(((LiteralQObject[]){ - QLIT_QINT(43), - QLIT_QINT(42), + QLIT_QNUM(43), + QLIT_QNUM(42), { } })), }, { .encoded = " [ 43 , { 'h' : 'b' }, [ ], 42 ]", .decoded = QLIT_QLIST(((LiteralQObject[]){ - QLIT_QINT(43), + QLIT_QNUM(43), QLIT_QDICT(((LiteralQDictEntry[]){ { "h", QLIT_QSTR("b") }, { }})), QLIT_QLIST(((LiteralQObject[]){ { }})), - QLIT_QINT(42), + QLIT_QNUM(42), { } })), }, { .encoded = " [ 43 , { 'h' : 'b' , 'a' : 32 }, [ ], 42 ]", .decoded = QLIT_QLIST(((LiteralQObject[]){ - QLIT_QINT(43), + QLIT_QNUM(43), QLIT_QDICT(((LiteralQDictEntry[]){ { "h", QLIT_QSTR("b") }, - { "a", QLIT_QINT(32) }, + { "a", QLIT_QNUM(32) }, { }})), QLIT_QLIST(((LiteralQObject[]){ { }})), - QLIT_QINT(42), + QLIT_QNUM(42), { } })), }, @@ -1327,11 +1377,11 @@ static void simple_varargs(void) QObject *embedded_obj; QObject *obj; LiteralQObject decoded = QLIT_QLIST(((LiteralQObject[]){ - QLIT_QINT(1), - QLIT_QINT(2), + QLIT_QNUM(1), + QLIT_QNUM(2), QLIT_QLIST(((LiteralQObject[]){ - QLIT_QINT(32), - QLIT_QINT(42), + QLIT_QNUM(32), + QLIT_QNUM(42), {}})), {}})); @@ -1468,6 +1518,7 @@ int main(int argc, char **argv) g_test_add_func("/literals/string/vararg", vararg_string); g_test_add_func("/literals/number/simple", simple_number); + g_test_add_func("/literals/number/large", large_number); g_test_add_func("/literals/number/float", float_number); g_test_add_func("/literals/number/vararg", vararg_number); diff --git a/tests/check-qlist.c b/tests/check-qlist.c index 4983867c27..894e9915e5 100644 --- a/tests/check-qlist.c +++ b/tests/check-qlist.c @@ -11,7 +11,8 @@ */ #include "qemu/osdep.h" -#include "qapi/qmp/qint.h" +#include "qapi/error.h" +#include "qapi/qmp/qnum.h" #include "qapi/qmp/qlist.h" /* @@ -29,17 +30,16 @@ static void qlist_new_test(void) g_assert(qlist->base.refcnt == 1); g_assert(qobject_type(QOBJECT(qlist)) == QTYPE_QLIST); - // destroy doesn't exist yet - g_free(qlist); + QDECREF(qlist); } static void qlist_append_test(void) { - QInt *qi; + QNum *qi; QList *qlist; QListEntry *entry; - qi = qint_from_int(42); + qi = qnum_from_int(42); qlist = qlist_new(); qlist_append(qlist, qi); @@ -48,10 +48,7 @@ static void qlist_append_test(void) g_assert(entry != NULL); g_assert(entry->value == QOBJECT(qi)); - // destroy doesn't exist yet - QDECREF(qi); - g_free(entry); - g_free(qlist); + QDECREF(qlist); } static void qobject_to_qlist_test(void) @@ -62,20 +59,6 @@ static void qobject_to_qlist_test(void) g_assert(qobject_to_qlist(QOBJECT(qlist)) == qlist); - // destroy doesn't exist yet - g_free(qlist); -} - -static void qlist_destroy_test(void) -{ - int i; - QList *qlist; - - qlist = qlist_new(); - - for (i = 0; i < 42; i++) - qlist_append_int(qlist, i); - QDECREF(qlist); } @@ -84,13 +67,17 @@ static const int iter_max = 42; static void iter_func(QObject *obj, void *opaque) { - QInt *qi; + QNum *qi; + int64_t val; g_assert(opaque == NULL); - qi = qobject_to_qint(obj); + qi = qobject_to_qnum(obj); g_assert(qi != NULL); - g_assert((qint_get_int(qi) >= 0) && (qint_get_int(qi) <= iter_max)); + + g_assert(qnum_get_try_int(qi, &val)); + g_assert_cmpint(val, >=, 0); + g_assert_cmpint(val, <=, iter_max); iter_called++; } @@ -120,7 +107,6 @@ int main(int argc, char **argv) g_test_add_func("/public/new", qlist_new_test); g_test_add_func("/public/append", qlist_append_test); g_test_add_func("/public/to_qlist", qobject_to_qlist_test); - g_test_add_func("/public/destroy", qlist_destroy_test); g_test_add_func("/public/iter", qlist_iter_test); return g_test_run(); diff --git a/tests/check-qnum.c b/tests/check-qnum.c new file mode 100644 index 0000000000..d702d5da9c --- /dev/null +++ b/tests/check-qnum.c @@ -0,0 +1,170 @@ +/* + * QNum unit-tests. + * + * Copyright (C) 2009 Red Hat Inc. + * Copyright IBM, Corp. 2009 + * + * Authors: + * Luiz Capitulino <lcapitulino@redhat.com> + * Anthony Liguori <aliguori@us.ibm.com> + * + * 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/osdep.h" + +#include "qapi/qmp/qnum.h" +#include "qapi/error.h" +#include "qemu-common.h" + +/* + * Public Interface test-cases + * + * (with some violations to access 'private' data) + */ + +static void qnum_from_int_test(void) +{ + QNum *qn; + const int value = -42; + + qn = qnum_from_int(value); + g_assert(qn != NULL); + g_assert_cmpint(qn->kind, ==, QNUM_I64); + g_assert_cmpint(qn->u.i64, ==, value); + g_assert_cmpint(qn->base.refcnt, ==, 1); + g_assert_cmpint(qobject_type(QOBJECT(qn)), ==, QTYPE_QNUM); + + QDECREF(qn); +} + +static void qnum_from_uint_test(void) +{ + QNum *qn; + const uint64_t value = UINT64_MAX; + + qn = qnum_from_uint(value); + g_assert(qn != NULL); + g_assert_cmpint(qn->kind, ==, QNUM_U64); + g_assert(qn->u.u64 == value); + g_assert(qn->base.refcnt == 1); + g_assert(qobject_type(QOBJECT(qn)) == QTYPE_QNUM); + + QDECREF(qn); +} + +static void qnum_from_double_test(void) +{ + QNum *qn; + const double value = -42.23423; + + qn = qnum_from_double(value); + g_assert(qn != NULL); + g_assert_cmpint(qn->kind, ==, QNUM_DOUBLE); + g_assert_cmpfloat(qn->u.dbl, ==, value); + g_assert_cmpint(qn->base.refcnt, ==, 1); + g_assert_cmpint(qobject_type(QOBJECT(qn)), ==, QTYPE_QNUM); + + QDECREF(qn); +} + +static void qnum_from_int64_test(void) +{ + QNum *qn; + const int64_t value = 0x1234567890abcdefLL; + + qn = qnum_from_int(value); + g_assert_cmpint((int64_t) qn->u.i64, ==, value); + + QDECREF(qn); +} + +static void qnum_get_int_test(void) +{ + QNum *qn; + const int value = 123456; + + qn = qnum_from_int(value); + g_assert_cmpint(qnum_get_int(qn), ==, value); + + QDECREF(qn); +} + +static void qnum_get_uint_test(void) +{ + QNum *qn; + const int value = 123456; + uint64_t val; + int64_t ival; + + qn = qnum_from_uint(value); + g_assert(qnum_get_try_uint(qn, &val)); + g_assert_cmpuint(val, ==, value); + QDECREF(qn); + + qn = qnum_from_int(value); + g_assert(qnum_get_try_uint(qn, &val)); + g_assert_cmpuint(val, ==, value); + QDECREF(qn); + + /* invalid cases */ + qn = qnum_from_int(-1); + g_assert(!qnum_get_try_uint(qn, &val)); + QDECREF(qn); + + qn = qnum_from_uint(-1ULL); + g_assert(!qnum_get_try_int(qn, &ival)); + QDECREF(qn); + + qn = qnum_from_double(0.42); + g_assert(!qnum_get_try_uint(qn, &val)); + QDECREF(qn); +} + +static void qobject_to_qnum_test(void) +{ + QNum *qn; + + qn = qnum_from_int(0); + g_assert(qobject_to_qnum(QOBJECT(qn)) == qn); + QDECREF(qn); + + qn = qnum_from_double(0); + g_assert(qobject_to_qnum(QOBJECT(qn)) == qn); + QDECREF(qn); +} + +static void qnum_to_string_test(void) +{ + QNum *qn; + char *tmp; + + qn = qnum_from_int(123456); + tmp = qnum_to_string(qn); + g_assert_cmpstr(tmp, ==, "123456"); + g_free(tmp); + QDECREF(qn); + + qn = qnum_from_double(0.42); + tmp = qnum_to_string(qn); + g_assert_cmpstr(tmp, ==, "0.42"); + g_free(tmp); + QDECREF(qn); +} + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + + g_test_add_func("/qnum/from_int", qnum_from_int_test); + g_test_add_func("/qnum/from_uint", qnum_from_uint_test); + g_test_add_func("/qnum/from_double", qnum_from_double_test); + g_test_add_func("/qnum/from_int64", qnum_from_int64_test); + g_test_add_func("/qnum/get_int", qnum_get_int_test); + g_test_add_func("/qnum/get_uint", qnum_get_uint_test); + g_test_add_func("/qnum/to_qnum", qobject_to_qnum_test); + g_test_add_func("/qnum/to_string", qnum_to_string_test); + + return g_test_run(); +} diff --git a/tests/check-qstring.c b/tests/check-qstring.c index 239e9d9da3..112ec08967 100644 --- a/tests/check-qstring.c +++ b/tests/check-qstring.c @@ -31,14 +31,6 @@ static void qstring_from_str_test(void) g_assert(strcmp(str, qstring->string) == 0); g_assert(qobject_type(QOBJECT(qstring)) == QTYPE_QSTRING); - // destroy doesn't exit yet - g_free(qstring->string); - g_free(qstring); -} - -static void qstring_destroy_test(void) -{ - QString *qstring = qstring_from_str("destroy test"); QDECREF(qstring); } @@ -97,7 +89,6 @@ int main(int argc, char **argv) g_test_init(&argc, &argv, NULL); g_test_add_func("/public/from_str", qstring_from_str_test); - g_test_add_func("/public/destroy", qstring_destroy_test); g_test_add_func("/public/get_str", qstring_get_str_test); g_test_add_func("/public/append_chr", qstring_append_chr_test); g_test_add_func("/public/from_substr", qstring_from_substr_test); diff --git a/tests/qapi-schema/comments.out b/tests/qapi-schema/comments.out index 5d7c13cad1..17e652535c 100644 --- a/tests/qapi-schema/comments.out +++ b/tests/qapi-schema/comments.out @@ -1,4 +1,4 @@ -enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool'] +enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool'] prefix QTYPE enum Status ['good', 'bad', 'ugly'] object q_empty diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out index 70c1252408..63ca25a8b9 100644 --- a/tests/qapi-schema/doc-good.out +++ b/tests/qapi-schema/doc-good.out @@ -6,7 +6,7 @@ object Object tag base1 case one: Variant1 case two: Variant2 -enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool'] +enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool'] prefix QTYPE object SugaredUnion member type: SugaredUnionKind optional=False diff --git a/tests/qapi-schema/empty.out b/tests/qapi-schema/empty.out index 8a5b034424..40b886ddae 100644 --- a/tests/qapi-schema/empty.out +++ b/tests/qapi-schema/empty.out @@ -1,3 +1,3 @@ -enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool'] +enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool'] prefix QTYPE object q_empty diff --git a/tests/qapi-schema/event-case.out b/tests/qapi-schema/event-case.out index 5a0f2bf805..313c0fe7be 100644 --- a/tests/qapi-schema/event-case.out +++ b/tests/qapi-schema/event-case.out @@ -1,4 +1,4 @@ -enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool'] +enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool'] prefix QTYPE event oops None boxed=False diff --git a/tests/qapi-schema/ident-with-escape.out b/tests/qapi-schema/ident-with-escape.out index 1d2722c02e..b5637cb2e0 100644 --- a/tests/qapi-schema/ident-with-escape.out +++ b/tests/qapi-schema/ident-with-escape.out @@ -1,4 +1,4 @@ -enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool'] +enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool'] prefix QTYPE command fooA q_obj_fooA-arg -> None gen=True success_response=True boxed=False diff --git a/tests/qapi-schema/include-relpath.out b/tests/qapi-schema/include-relpath.out index 5d7c13cad1..17e652535c 100644 --- a/tests/qapi-schema/include-relpath.out +++ b/tests/qapi-schema/include-relpath.out @@ -1,4 +1,4 @@ -enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool'] +enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool'] prefix QTYPE enum Status ['good', 'bad', 'ugly'] object q_empty diff --git a/tests/qapi-schema/include-repetition.out b/tests/qapi-schema/include-repetition.out index 5d7c13cad1..17e652535c 100644 --- a/tests/qapi-schema/include-repetition.out +++ b/tests/qapi-schema/include-repetition.out @@ -1,4 +1,4 @@ -enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool'] +enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool'] prefix QTYPE enum Status ['good', 'bad', 'ugly'] object q_empty diff --git a/tests/qapi-schema/include-simple.out b/tests/qapi-schema/include-simple.out index 5d7c13cad1..17e652535c 100644 --- a/tests/qapi-schema/include-simple.out +++ b/tests/qapi-schema/include-simple.out @@ -1,4 +1,4 @@ -enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool'] +enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool'] prefix QTYPE enum Status ['good', 'bad', 'ugly'] object q_empty diff --git a/tests/qapi-schema/indented-expr.out b/tests/qapi-schema/indented-expr.out index e8171c935f..586795f44d 100644 --- a/tests/qapi-schema/indented-expr.out +++ b/tests/qapi-schema/indented-expr.out @@ -1,4 +1,4 @@ -enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool'] +enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool'] prefix QTYPE command eins None -> None gen=True success_response=True boxed=False diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json index 17649c6398..91ffb2648c 100644 --- a/tests/qapi-schema/qapi-schema-test.json +++ b/tests/qapi-schema/qapi-schema-test.json @@ -103,8 +103,6 @@ { 'alternate': 'AltEnumNum', 'data': { 'e': 'EnumOne', 'n': 'number' } } { 'alternate': 'AltNumEnum', 'data': { 'n': 'number', 'e': 'EnumOne' } } { 'alternate': 'AltEnumInt', 'data': { 'e': 'EnumOne', 'i': 'int' } } -{ 'alternate': 'AltIntNum', 'data': { 'i': 'int', 'n': 'number' } } -{ 'alternate': 'AltNumInt', 'data': { 'n': 'number', 'i': 'int' } } # for testing use of 'str' within alternates { 'alternate': 'AltStrObj', 'data': { 's': 'str', 'o': 'TestStruct' } } diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out index 9f68610dc2..b88b8aae6f 100644 --- a/tests/qapi-schema/qapi-schema-test.out +++ b/tests/qapi-schema/qapi-schema-test.out @@ -10,18 +10,10 @@ alternate AltEnumNum tag type case e: EnumOne case n: number -alternate AltIntNum - tag type - case i: int - case n: number alternate AltNumEnum tag type case n: number case e: EnumOne -alternate AltNumInt - tag type - case n: number - case i: int alternate AltStrObj tag type case s: str @@ -58,7 +50,7 @@ object NestedEnumsOne member enum4: EnumOne optional=True enum QEnumTwo ['value1', 'value2'] prefix QENUM_TWO -enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool'] +enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool'] prefix QTYPE object TestStruct member integer: int optional=False diff --git a/tests/test-keyval.c b/tests/test-keyval.c index c3be00524c..baf7e339ab 100644 --- a/tests/test-keyval.c +++ b/tests/test-keyval.c @@ -615,7 +615,7 @@ static void test_keyval_visit_alternate(void) Visitor *v; QDict *qdict; AltStrObj *aso; - AltNumInt *ani; + AltNumEnum *ane; AltEnumBool *aeb; /* @@ -631,7 +631,7 @@ static void test_keyval_visit_alternate(void) g_assert_cmpint(aso->type, ==, QTYPE_QSTRING); g_assert_cmpstr(aso->u.s, ==, "1"); qapi_free_AltStrObj(aso); - visit_type_AltNumInt(v, "b", &ani, &err); + visit_type_AltNumEnum(v, "b", &ane, &err); error_free_or_abort(&err); visit_type_AltEnumBool(v, "c", &aeb, &err); error_free_or_abort(&err); diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c index acdded4d67..904c89d4d4 100644 --- a/tests/test-qmp-commands.c +++ b/tests/test-qmp-commands.c @@ -162,7 +162,8 @@ static void test_dispatch_cmd_io(void) QDict *ud1b = qdict_new(); QDict *ret, *ret_dict, *ret_dict_dict, *ret_dict_dict_userdef; QDict *ret_dict_dict2, *ret_dict_dict2_userdef; - QInt *ret3; + QNum *ret3; + int64_t val; qdict_put_int(ud1a, "integer", 42); qdict_put_str(ud1a, "string", "hello"); @@ -194,8 +195,9 @@ static void test_dispatch_cmd_io(void) qdict_put(req, "arguments", args3); qdict_put_str(req, "execute", "guest-get-time"); - ret3 = qobject_to_qint(test_qmp_dispatch(req)); - assert(qint_get_int(ret3) == 66); + ret3 = qobject_to_qnum(test_qmp_dispatch(req)); + g_assert(qnum_get_try_int(ret3, &val)); + g_assert_cmpint(val, ==, 66); QDECREF(ret3); QDECREF(req); diff --git a/tests/test-qmp-event.c b/tests/test-qmp-event.c index 4c0f09601d..9fb3c5e81e 100644 --- a/tests/test-qmp-event.c +++ b/tests/test-qmp-event.c @@ -18,7 +18,6 @@ #include "test-qapi-visit.h" #include "test-qapi-event.h" #include "qapi/qmp/types.h" -#include "qapi/qmp/qint.h" #include "qapi/qmp/qobject.h" #include "qapi/qmp-event.h" @@ -41,6 +40,7 @@ void qdict_cmp_do_simple(const char *key, QObject *obj1, void *opaque) { QObject *obj2; QDictCmpData d_new, *d = opaque; + int64_t val1, val2; if (!d->result) { return; @@ -62,9 +62,10 @@ void qdict_cmp_do_simple(const char *key, QObject *obj1, void *opaque) d->result = (qbool_get_bool(qobject_to_qbool(obj1)) == qbool_get_bool(qobject_to_qbool(obj2))); return; - case QTYPE_QINT: - d->result = (qint_get_int(qobject_to_qint(obj1)) == - qint_get_int(qobject_to_qint(obj2))); + case QTYPE_QNUM: + g_assert(qnum_get_try_int(qobject_to_qnum(obj1), &val1)); + g_assert(qnum_get_try_int(qobject_to_qnum(obj2), &val2)); + d->result = val1 == val2; return; case QTYPE_QSTRING: d->result = g_strcmp0(qstring_get_str(qobject_to_qstring(obj1)), diff --git a/tests/test-qobject-input-visitor.c b/tests/test-qobject-input-visitor.c index 6b997a177d..34bab8a913 100644 --- a/tests/test-qobject-input-visitor.c +++ b/tests/test-qobject-input-visitor.c @@ -107,6 +107,7 @@ static void test_visitor_in_int(TestInputVisitorData *data, const void *unused) { int64_t res = 0; + double dbl; int value = -42; Visitor *v; @@ -114,13 +115,17 @@ static void test_visitor_in_int(TestInputVisitorData *data, visit_type_int(v, NULL, &res, &error_abort); g_assert_cmpint(res, ==, value); + + visit_type_number(v, NULL, &dbl, &error_abort); + g_assert_cmpfloat(dbl, ==, -42.0); } static void test_visitor_in_uint(TestInputVisitorData *data, const void *unused) { - Error *err = NULL; uint64_t res = 0; + int64_t i64; + double dbl; int value = 42; Visitor *v; @@ -129,19 +134,25 @@ static void test_visitor_in_uint(TestInputVisitorData *data, visit_type_uint64(v, NULL, &res, &error_abort); g_assert_cmpuint(res, ==, (uint64_t)value); - /* BUG: value between INT64_MIN and -1 accepted modulo 2^64 */ + visit_type_int(v, NULL, &i64, &error_abort); + g_assert_cmpint(i64, ==, value); + + visit_type_number(v, NULL, &dbl, &error_abort); + g_assert_cmpfloat(dbl, ==, value); + /* BUG: value between INT64_MIN and -1 accepted modulo 2^64 */ v = visitor_input_test_init(data, "%d", -value); visit_type_uint64(v, NULL, &res, &error_abort); g_assert_cmpuint(res, ==, (uint64_t)-value); - /* BUG: value between INT64_MAX+1 and UINT64_MAX rejected */ - v = visitor_input_test_init(data, "18446744073709551574"); - visit_type_uint64(v, NULL, &res, &err); - error_free_or_abort(&err); + visit_type_uint64(v, NULL, &res, &error_abort); + g_assert_cmpuint(res, ==, 18446744073709551574U); + + visit_type_number(v, NULL, &dbl, &error_abort); + g_assert_cmpfloat(dbl, ==, 18446744073709552000.0); } static void test_visitor_in_int_overflow(TestInputVisitorData *data, @@ -151,9 +162,10 @@ static void test_visitor_in_int_overflow(TestInputVisitorData *data, Error *err = NULL; Visitor *v; - /* this will overflow a Qint/int64, so should be deserialized into - * a QFloat/double field instead, leading to an error if we pass it - * to visit_type_int. confirm this. + /* + * This will overflow a QNUM_I64, so should be deserialized into a + * QNUM_DOUBLE field instead, leading to an error if we pass it to + * visit_type_int(). Confirm this. */ v = visitor_input_test_init(data, "%f", DBL_MAX); @@ -260,6 +272,27 @@ static void test_visitor_in_number(TestInputVisitorData *data, g_assert_cmpfloat(res, ==, value); } +static void test_visitor_in_large_number(TestInputVisitorData *data, + const void *unused) +{ + Error *err = NULL; + double res = 0; + int64_t i64; + uint64_t u64; + Visitor *v; + + v = visitor_input_test_init(data, "-18446744073709551616"); /* -2^64 */ + + visit_type_number(v, NULL, &res, &error_abort); + g_assert_cmpfloat(res, ==, -18446744073709552e3); + + visit_type_int(v, NULL, &i64, &err); + error_free_or_abort(&err); + + visit_type_uint64(v, NULL, &u64, &err); + error_free_or_abort(&err); +} + static void test_visitor_in_number_keyval(TestInputVisitorData *data, const void *unused) { @@ -434,17 +467,19 @@ static void test_visitor_in_any(TestInputVisitorData *data, { QObject *res = NULL; Visitor *v; - QInt *qint; + QNum *qnum; QBool *qbool; QString *qstring; QDict *qdict; QObject *qobj; + int64_t val; v = visitor_input_test_init(data, "-42"); visit_type_any(v, NULL, &res, &error_abort); - qint = qobject_to_qint(res); - g_assert(qint); - g_assert_cmpint(qint_get_int(qint), ==, -42); + qnum = qobject_to_qnum(res); + g_assert(qnum); + g_assert(qnum_get_try_int(qnum, &val)); + g_assert_cmpint(val, ==, -42); qobject_decref(res); v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }"); @@ -453,9 +488,10 @@ static void test_visitor_in_any(TestInputVisitorData *data, g_assert(qdict && qdict_size(qdict) == 3); qobj = qdict_get(qdict, "integer"); g_assert(qobj); - qint = qobject_to_qint(qobj); - g_assert(qint); - g_assert_cmpint(qint_get_int(qint), ==, -42); + qnum = qobject_to_qnum(qobj); + g_assert(qnum); + g_assert(qnum_get_try_int(qnum, &val)); + g_assert_cmpint(val, ==, -42); qobj = qdict_get(qdict, "boolean"); g_assert(qobj); qbool = qobject_to_qbool(qobj); @@ -533,7 +569,7 @@ static void test_visitor_in_alternate(TestInputVisitorData *data, v = visitor_input_test_init(data, "42"); visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort); - g_assert_cmpint(tmp->type, ==, QTYPE_QINT); + g_assert_cmpint(tmp->type, ==, QTYPE_QNUM); g_assert_cmpint(tmp->u.i, ==, 42); qapi_free_UserDefAlternate(tmp); @@ -561,7 +597,7 @@ static void test_visitor_in_alternate(TestInputVisitorData *data, v = visitor_input_test_init(data, "{ 'alt': 42 }"); visit_type_WrapAlternate(v, NULL, &wrap, &error_abort); - g_assert_cmpint(wrap->alt->type, ==, QTYPE_QINT); + g_assert_cmpint(wrap->alt->type, ==, QTYPE_QNUM); g_assert_cmpint(wrap->alt->u.i, ==, 42); qapi_free_WrapAlternate(wrap); @@ -592,8 +628,6 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data, AltEnumNum *aen; AltNumEnum *ans; AltEnumInt *asi; - AltIntNum *ain; - AltNumInt *ani; /* Parsing an int */ @@ -604,34 +638,22 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data, v = visitor_input_test_init(data, "42"); visit_type_AltEnumNum(v, NULL, &aen, &error_abort); - g_assert_cmpint(aen->type, ==, QTYPE_QFLOAT); + g_assert_cmpint(aen->type, ==, QTYPE_QNUM); g_assert_cmpfloat(aen->u.n, ==, 42); qapi_free_AltEnumNum(aen); v = visitor_input_test_init(data, "42"); visit_type_AltNumEnum(v, NULL, &ans, &error_abort); - g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT); + g_assert_cmpint(ans->type, ==, QTYPE_QNUM); g_assert_cmpfloat(ans->u.n, ==, 42); qapi_free_AltNumEnum(ans); v = visitor_input_test_init(data, "42"); visit_type_AltEnumInt(v, NULL, &asi, &error_abort); - g_assert_cmpint(asi->type, ==, QTYPE_QINT); + g_assert_cmpint(asi->type, ==, QTYPE_QNUM); g_assert_cmpint(asi->u.i, ==, 42); qapi_free_AltEnumInt(asi); - v = visitor_input_test_init(data, "42"); - visit_type_AltIntNum(v, NULL, &ain, &error_abort); - g_assert_cmpint(ain->type, ==, QTYPE_QINT); - g_assert_cmpint(ain->u.i, ==, 42); - qapi_free_AltIntNum(ain); - - v = visitor_input_test_init(data, "42"); - visit_type_AltNumInt(v, NULL, &ani, &error_abort); - g_assert_cmpint(ani->type, ==, QTYPE_QINT); - g_assert_cmpint(ani->u.i, ==, 42); - qapi_free_AltNumInt(ani); - /* Parsing a double */ v = visitor_input_test_init(data, "42.5"); @@ -641,13 +663,13 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data, v = visitor_input_test_init(data, "42.5"); visit_type_AltEnumNum(v, NULL, &aen, &error_abort); - g_assert_cmpint(aen->type, ==, QTYPE_QFLOAT); + g_assert_cmpint(aen->type, ==, QTYPE_QNUM); g_assert_cmpfloat(aen->u.n, ==, 42.5); qapi_free_AltEnumNum(aen); v = visitor_input_test_init(data, "42.5"); visit_type_AltNumEnum(v, NULL, &ans, &error_abort); - g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT); + g_assert_cmpint(ans->type, ==, QTYPE_QNUM); g_assert_cmpfloat(ans->u.n, ==, 42.5); qapi_free_AltNumEnum(ans); @@ -655,18 +677,6 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data, visit_type_AltEnumInt(v, NULL, &asi, &err); error_free_or_abort(&err); qapi_free_AltEnumInt(asi); - - v = visitor_input_test_init(data, "42.5"); - visit_type_AltIntNum(v, NULL, &ain, &error_abort); - g_assert_cmpint(ain->type, ==, QTYPE_QFLOAT); - g_assert_cmpfloat(ain->u.n, ==, 42.5); - qapi_free_AltIntNum(ain); - - v = visitor_input_test_init(data, "42.5"); - visit_type_AltNumInt(v, NULL, &ani, &error_abort); - g_assert_cmpint(ani->type, ==, QTYPE_QFLOAT); - g_assert_cmpfloat(ani->u.n, ==, 42.5); - qapi_free_AltNumInt(ani); } static void test_native_list_integer_helper(TestInputVisitorData *data, @@ -1092,7 +1102,7 @@ static void test_visitor_in_fail_struct_missing(TestInputVisitorData *data, error_free_or_abort(&err); visit_start_list(v, "list", NULL, 0, &err); error_free_or_abort(&err); - visit_start_alternate(v, "alternate", &alt, sizeof(*alt), false, &err); + visit_start_alternate(v, "alternate", &alt, sizeof(*alt), &err); error_free_or_abort(&err); visit_optional(v, "optional", &present); g_assert(!present); @@ -1279,6 +1289,8 @@ int main(int argc, char **argv) NULL, test_visitor_in_bool_str_fail); input_visitor_test_add("/visitor/input/number", NULL, test_visitor_in_number); + input_visitor_test_add("/visitor/input/large_number", + NULL, test_visitor_in_large_number); input_visitor_test_add("/visitor/input/number_keyval", NULL, test_visitor_in_number_keyval); input_visitor_test_add("/visitor/input/number_str_keyval", diff --git a/tests/test-qobject-output-visitor.c b/tests/test-qobject-output-visitor.c index 4e8fdf1397..749c54065f 100644 --- a/tests/test-qobject-output-visitor.c +++ b/tests/test-qobject-output-visitor.c @@ -58,13 +58,15 @@ static void test_visitor_out_int(TestOutputVisitorData *data, const void *unused) { int64_t value = -42; - QInt *qint; + int64_t val; + QNum *qnum; visit_type_int(data->ov, NULL, &value, &error_abort); - qint = qobject_to_qint(visitor_get(data)); - g_assert(qint); - g_assert_cmpint(qint_get_int(qint), ==, value); + qnum = qobject_to_qnum(visitor_get(data)); + g_assert(qnum); + g_assert(qnum_get_try_int(qnum, &val)); + g_assert_cmpint(val, ==, value); } static void test_visitor_out_bool(TestOutputVisitorData *data, @@ -84,13 +86,13 @@ static void test_visitor_out_number(TestOutputVisitorData *data, const void *unused) { double value = 3.14; - QFloat *qfloat; + QNum *qnum; visit_type_number(data->ov, NULL, &value, &error_abort); - qfloat = qobject_to_qfloat(visitor_get(data)); - g_assert(qfloat); - g_assert(qfloat_get_double(qfloat) == value); + qnum = qobject_to_qnum(visitor_get(data)); + g_assert(qnum); + g_assert(qnum_get_double(qnum) == value); } static void test_visitor_out_string(TestOutputVisitorData *data, @@ -329,16 +331,18 @@ static void test_visitor_out_any(TestOutputVisitorData *data, const void *unused) { QObject *qobj; - QInt *qint; + QNum *qnum; QBool *qbool; QString *qstring; QDict *qdict; + int64_t val; - qobj = QOBJECT(qint_from_int(-42)); + qobj = QOBJECT(qnum_from_int(-42)); visit_type_any(data->ov, NULL, &qobj, &error_abort); - qint = qobject_to_qint(visitor_get(data)); - g_assert(qint); - g_assert_cmpint(qint_get_int(qint), ==, -42); + qnum = qobject_to_qnum(visitor_get(data)); + g_assert(qnum); + g_assert(qnum_get_try_int(qnum, &val)); + g_assert_cmpint(val, ==, -42); qobject_decref(qobj); visitor_reset(data); @@ -351,9 +355,10 @@ static void test_visitor_out_any(TestOutputVisitorData *data, qobject_decref(qobj); qdict = qobject_to_qdict(visitor_get(data)); g_assert(qdict); - qint = qobject_to_qint(qdict_get(qdict, "integer")); - g_assert(qint); - g_assert_cmpint(qint_get_int(qint), ==, -42); + qnum = qobject_to_qnum(qdict_get(qdict, "integer")); + g_assert(qnum); + g_assert(qnum_get_try_int(qnum, &val)); + g_assert_cmpint(val, ==, -42); qbool = qobject_to_qbool(qdict_get(qdict, "boolean")); g_assert(qbool); g_assert(qbool_get_bool(qbool) == true); @@ -388,18 +393,20 @@ static void test_visitor_out_alternate(TestOutputVisitorData *data, const void *unused) { UserDefAlternate *tmp; - QInt *qint; + QNum *qnum; QString *qstr; QDict *qdict; + int64_t val; tmp = g_new0(UserDefAlternate, 1); - tmp->type = QTYPE_QINT; + tmp->type = QTYPE_QNUM; tmp->u.i = 42; visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort); - qint = qobject_to_qint(visitor_get(data)); - g_assert(qint); - g_assert_cmpint(qint_get_int(qint), ==, 42); + qnum = qobject_to_qnum(visitor_get(data)); + g_assert(qnum); + g_assert(qnum_get_try_int(qnum, &val)); + g_assert_cmpint(val, ==, 42); qapi_free_UserDefAlternate(tmp); @@ -595,26 +602,44 @@ static void check_native_list(QObject *qobj, qlist = qlist_copy(qobject_to_qlist(qdict_get(qdict, "data"))); switch (kind) { - case USER_DEF_NATIVE_LIST_UNION_KIND_S8: - case USER_DEF_NATIVE_LIST_UNION_KIND_S16: - case USER_DEF_NATIVE_LIST_UNION_KIND_S32: - case USER_DEF_NATIVE_LIST_UNION_KIND_S64: case USER_DEF_NATIVE_LIST_UNION_KIND_U8: case USER_DEF_NATIVE_LIST_UNION_KIND_U16: case USER_DEF_NATIVE_LIST_UNION_KIND_U32: case USER_DEF_NATIVE_LIST_UNION_KIND_U64: - /* all integer elements in JSON arrays get stored into QInts when - * we convert to QObjects, so we can check them all in the same - * fashion, so simply fall through here + for (i = 0; i < 32; i++) { + QObject *tmp; + QNum *qvalue; + uint64_t val; + + tmp = qlist_peek(qlist); + g_assert(tmp); + qvalue = qobject_to_qnum(tmp); + g_assert(qnum_get_try_uint(qvalue, &val)); + g_assert_cmpint(val, ==, i); + qobject_decref(qlist_pop(qlist)); + } + break; + + case USER_DEF_NATIVE_LIST_UNION_KIND_S8: + case USER_DEF_NATIVE_LIST_UNION_KIND_S16: + case USER_DEF_NATIVE_LIST_UNION_KIND_S32: + case USER_DEF_NATIVE_LIST_UNION_KIND_S64: + /* + * All integer elements in JSON arrays get stored into QNums + * when we convert to QObjects, so we can check them all in + * the same fashion, so simply fall through here. */ case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER: for (i = 0; i < 32; i++) { QObject *tmp; - QInt *qvalue; + QNum *qvalue; + int64_t val; + tmp = qlist_peek(qlist); g_assert(tmp); - qvalue = qobject_to_qint(tmp); - g_assert_cmpint(qint_get_int(qvalue), ==, i); + qvalue = qobject_to_qnum(tmp); + g_assert(qnum_get_try_int(qvalue, &val)); + g_assert_cmpint(val, ==, i); qobject_decref(qlist_pop(qlist)); } break; @@ -645,15 +670,15 @@ static void check_native_list(QObject *qobj, case USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER: for (i = 0; i < 32; i++) { QObject *tmp; - QFloat *qvalue; + QNum *qvalue; GString *double_expected = g_string_new(""); GString *double_actual = g_string_new(""); tmp = qlist_peek(qlist); g_assert(tmp); - qvalue = qobject_to_qfloat(tmp); + qvalue = qobject_to_qnum(tmp); g_string_printf(double_expected, "%.6f", (double)i / 3); - g_string_printf(double_actual, "%.6f", qfloat_get_double(qvalue)); + g_string_printf(double_actual, "%.6f", qnum_get_double(qvalue)); g_assert_cmpstr(double_actual->str, ==, double_expected->str); qobject_decref(qlist_pop(qlist)); diff --git a/tests/test-x86-cpuid-compat.c b/tests/test-x86-cpuid-compat.c index 4166ce54b7..58a2dd9fe8 100644 --- a/tests/test-x86-cpuid-compat.c +++ b/tests/test-x86-cpuid-compat.c @@ -1,9 +1,8 @@ #include "qemu/osdep.h" #include "qemu-common.h" -#include "qapi/qmp/qlist.h" -#include "qapi/qmp/qstring.h" +#include "qapi/error.h" #include "qapi/qmp/qdict.h" -#include "qapi/qmp/qint.h" +#include "qapi/qmp/qnum.h" #include "qapi/qmp/qbool.h" #include "libqtest.h" @@ -57,12 +56,14 @@ static void test_cpuid_prop(const void *data) { const CpuidTestArgs *args = data; char *path; - QInt *value; + QNum *value; + int64_t val; qtest_start(args->cmdline); path = get_cpu0_qom_path(); - value = qobject_to_qint(qom_get(path, args->property)); - g_assert_cmpint(qint_get_int(value), ==, args->expected_value); + value = qobject_to_qnum(qom_get(path, args->property)); + g_assert(qnum_get_try_int(value, &val)); + g_assert_cmpint(val, ==, args->expected_value); qtest_end(); QDECREF(value); @@ -109,12 +110,15 @@ static uint32_t get_feature_word(QList *features, uint32_t eax, uint32_t ecx, uint32_t reax = qdict_get_int(w, "cpuid-input-eax"); bool has_ecx = qdict_haskey(w, "cpuid-input-ecx"); uint32_t recx = 0; + int64_t val; if (has_ecx) { recx = qdict_get_int(w, "cpuid-input-ecx"); } if (eax == reax && (!has_ecx || ecx == recx) && !strcmp(rreg, reg)) { - return qint_get_int(qobject_to_qint(qdict_get(w, "features"))); + g_assert(qnum_get_try_int(qobject_to_qnum(qdict_get(w, "features")), + &val)); + return val; } } return 0; diff --git a/ui/console.c b/ui/console.c index d914cced53..40572c9254 100644 --- a/ui/console.c +++ b/ui/console.c @@ -1872,8 +1872,8 @@ QemuConsole *qemu_console_lookup_by_device(DeviceState *dev, uint32_t head) if (DEVICE(obj) != dev) { continue; } - h = object_property_get_int(OBJECT(consoles[i]), - "head", &error_abort); + h = object_property_get_uint(OBJECT(consoles[i]), + "head", &error_abort); if (h != head) { continue; } diff --git a/ui/spice-core.c b/ui/spice-core.c index 182f550f1f..ea04dc69b5 100644 --- a/ui/spice-core.c +++ b/ui/spice-core.c @@ -30,7 +30,6 @@ #include "qemu-x509.h" #include "qemu/sockets.h" #include "qmp-commands.h" -#include "qapi/qmp/qint.h" #include "qapi/qmp/qbool.h" #include "qapi/qmp/qstring.h" #include "qapi/qmp/qjson.h" diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c index 1e53b1cf84..89ab12c0d8 100644 --- a/ui/vnc-enc-tight.c +++ b/ui/vnc-enc-tight.c @@ -44,7 +44,6 @@ #endif #include "qemu/bswap.h" -#include "qapi/qmp/qint.h" #include "vnc.h" #include "vnc-enc-tight.h" #include "vnc-palette.h" diff --git a/util/qemu-option.c b/util/qemu-option.c index 5977bfc3e9..9b1dc8093b 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -941,9 +941,8 @@ typedef struct OptsFromQDictState { static void qemu_opts_from_qdict_1(const char *key, QObject *obj, void *opaque) { OptsFromQDictState *state = opaque; - char buf[32]; + char buf[32], *tmp = NULL; const char *value; - int n; if (!strcmp(key, "id") || *state->errp) { return; @@ -953,17 +952,9 @@ static void qemu_opts_from_qdict_1(const char *key, QObject *obj, void *opaque) case QTYPE_QSTRING: value = qstring_get_str(qobject_to_qstring(obj)); break; - case QTYPE_QINT: - n = snprintf(buf, sizeof(buf), "%" PRId64, - qint_get_int(qobject_to_qint(obj))); - assert(n < sizeof(buf)); - value = buf; - break; - case QTYPE_QFLOAT: - n = snprintf(buf, sizeof(buf), "%.17g", - qfloat_get_double(qobject_to_qfloat(obj))); - assert(n < sizeof(buf)); - value = buf; + case QTYPE_QNUM: + tmp = qnum_to_string(qobject_to_qnum(obj)); + value = tmp; break; case QTYPE_QBOOL: pstrcpy(buf, sizeof(buf), @@ -975,13 +966,14 @@ static void qemu_opts_from_qdict_1(const char *key, QObject *obj, void *opaque) } qemu_opt_set(state->opts, key, value, state->errp); + g_free(tmp); } /* * Create QemuOpts from a QDict. - * Use value of key "id" as ID if it exists and is a QString. - * Only QStrings, QInts, QFloats and QBools are copied. Entries with - * other types are silently ignored. + * Use value of key "id" as ID if it exists and is a QString. Only + * QStrings, QNums and QBools are copied. Entries with other types + * are silently ignored. */ QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict, Error **errp) |