qapi: merge QInt and QFloat in QNum

We would like to use a same QObject type to represent numbers, whether
they are int, uint, or floats. Getters will allow some compatibility
between the various types if the number fits other representations.

Add a few more tests while at it.

Backports commit 01b2ffcedd94ad7b42bc870e4c6936c87ad03429 from qemu
This commit is contained in:
Marc-André Lureau 2018-03-03 17:43:24 -05:00 committed by Lioncash
parent f1dbfe6be6
commit dd77730d49
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
21 changed files with 280 additions and 283 deletions

View file

@ -34,11 +34,10 @@ void qapi_free_DummyForceArrays(DummyForceArrays *obj)
const char *const QType_lookup[] = { const char *const QType_lookup[] = {
"none", "none",
"qnull", "qnull",
"qint", "qnum",
"qstring", "qstring",
"qdict", "qdict",
"qlist", "qlist",
"qfloat",
"qbool", "qbool",
NULL, NULL,
}; };

View file

@ -26,13 +26,12 @@
typedef enum QType { typedef enum QType {
QTYPE_NONE = 0, QTYPE_NONE = 0,
QTYPE_QNULL = 1, QTYPE_QNULL = 1,
QTYPE_QINT = 2, QTYPE_QNUM = 2,
QTYPE_QSTRING = 3, QTYPE_QSTRING = 3,
QTYPE_QDICT = 4, QTYPE_QDICT = 4,
QTYPE_QLIST = 5, QTYPE_QLIST = 5,
QTYPE_QFLOAT = 6, QTYPE_QBOOL = 6,
QTYPE_QBOOL = 7, QTYPE__MAX = 7,
QTYPE__MAX = 8,
} QType; } QType;
extern const char *const QType_lookup[]; extern const char *const QType_lookup[];

View file

@ -15,6 +15,7 @@
#include "qapi/qmp/qobject.h" #include "qapi/qmp/qobject.h"
#include "qapi/qmp/qlist.h" #include "qapi/qmp/qlist.h"
#include "qapi/qmp/qnum.h"
#include "qemu/queue.h" #include "qemu/queue.h"
#include "unicorn/platform.h" #include "unicorn/platform.h"
@ -55,7 +56,7 @@ void qdict_destroy_obj(QObject *obj);
/* Helpers for int, bool, and string */ /* Helpers for int, bool, and string */
#define qdict_put_int(qdict, key, value) \ #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) \ #define qdict_put_bool(qdict, key, value) \
qdict_put(qdict, key, qbool_from_bool(value)) qdict_put(qdict, key, qbool_from_bool(value))
#define qdict_put_str(qdict, key, value) \ #define qdict_put_str(qdict, key, value) \

View file

@ -1,30 +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 "unicorn/platform.h"
#include "qapi/qmp/qobject.h"
typedef struct QFloat {
QObject_HEAD;
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 */

View file

@ -1,29 +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 "unicorn/platform.h"
#include "qapi/qmp/qobject.h"
typedef struct QInt {
QObject_HEAD;
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 */

View file

@ -14,6 +14,7 @@
#define QLIST_H #define QLIST_H
#include "qapi/qmp/qobject.h" #include "qapi/qmp/qobject.h"
#include "qapi/qmp/qnum.h"
#include "qemu/queue.h" #include "qemu/queue.h"
typedef struct QListEntry { typedef struct QListEntry {
@ -31,7 +32,7 @@ typedef struct QList {
/* Helpers for int, bool, and string */ /* Helpers for int, bool, and string */
#define qlist_append_int(qlist, value) \ #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) \ #define qlist_append_bool(qlist, value) \
qlist_append(qlist, qbool_from_bool(value)) qlist_append(qlist, qbool_from_bool(value))
#define qlist_append_str(qlist, value) \ #define qlist_append_str(qlist, value) \

View file

@ -0,0 +1,46 @@
/*
* 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_DOUBLE
} QNumKind;
typedef struct QNum {
QObject base;
QNumKind kind;
union {
int64_t i64;
double dbl;
} u;
} QNum;
QNum *qnum_from_int(int64_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);
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 */

View file

@ -14,8 +14,7 @@
#define QAPI_QMP_TYPES_H #define QAPI_QMP_TYPES_H
#include "qapi/qmp/qobject.h" #include "qapi/qmp/qobject.h"
#include "qapi/qmp/qint.h" #include "qapi/qmp/qnum.h"
#include "qapi/qmp/qfloat.h"
#include "qapi/qmp/qbool.h" #include "qapi/qmp/qbool.h"
#include "qapi/qmp/qstring.h" #include "qapi/qmp/qstring.h"
#include "qapi/qmp/qdict.h" #include "qapi/qmp/qdict.h"

View file

@ -30,9 +30,9 @@ typedef struct QObjectInputVisitor QObjectInputVisitor;
* visit_type_FOO() creates an instance of QAPI type FOO. The visited * visit_type_FOO() creates an instance of QAPI type FOO. The visited
* QObject must match FOO. QDict matches struct/union types, QList * QObject must match FOO. QDict matches struct/union types, QList
* matches list types, QString matches type 'str' and enumeration * matches list types, QString matches type 'str' and enumeration
* types, QInt matches integer types, QFloat matches type 'number', * types, QNum matches integer and float types, QBool matches type
* QBool matches type 'bool'. Type 'any' is matched by QObject. A * 'bool'. Type 'any' is matched by QObject. A QAPI alternate type
* QAPI alternate type is matched when one of its member types is. * is matched when one of its member types is.
* *
* visit_start_struct() ... visit_end_struct() visits a QDict and * visit_start_struct() ... visit_end_struct() visits a QDict and
* creates a QAPI struct/union. Visits in between visit the * creates a QAPI struct/union. Visits in between visit the

View file

@ -28,10 +28,10 @@ typedef struct QObjectOutputVisitor QObjectOutputVisitor;
* *
* visit_type_FOO() creates a QObject for QAPI type FOO. It creates a * 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 * QDict for struct/union types, a QList for list types, QString for
* type 'str' and enumeration types, QInt for integer types, QFloat * type 'str' and enumeration types, QNum for integer and float
* for type 'number', QBool for type 'bool'. For type 'any', it * types, QBool for type 'bool'. For type 'any', it increments the
* increments the QObject's reference count. For QAPI alternate * QObject's reference count. For QAPI alternate types, it creates
* types, it creates the QObject for the member that is in use. * the QObject for the member that is in use.
* *
* visit_start_struct() ... visit_end_struct() visits a QAPI * visit_start_struct() ... visit_end_struct() visits a QAPI
* struct/union and creates a QDict. Visits in between visit the * struct/union and creates a QDict. Visits in between visit the

View file

@ -336,9 +336,6 @@ static void qobject_input_start_alternate(Visitor *v, const char *name,
} }
*obj = g_malloc0(size); *obj = g_malloc0(size);
(*obj)->type = qobject_type(qobj); (*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, static void qobject_input_type_int64(Visitor *v, const char *name, int64_t *obj,
@ -346,40 +343,36 @@ static void qobject_input_type_int64(Visitor *v, const char *name, int64_t *obj,
{ {
QObjectInputVisitor *qiv = to_qiv(v); QObjectInputVisitor *qiv = to_qiv(v);
QObject *qobj = qobject_input_get_object(qiv, name, true, errp); QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
QInt *qint; QNum *qnum;
if (!qobj) { if (!qobj) {
return; return;
} }
qint = qobject_to_qint(qobj); qnum = qobject_to_qnum(qobj);
if (!qint) { if (!qnum || !qnum_get_try_int(qnum, obj)) {
error_setg(errp, QERR_INVALID_PARAMETER_TYPE, error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
full_name(qiv, name), "integer"); full_name(qiv, name), "integer");
return;
} }
*obj = qint_get_int(qint);
} }
static void qobject_input_type_uint64(Visitor *v, const char *name, uint64_t *obj, static void qobject_input_type_uint64(Visitor *v, const char *name, uint64_t *obj,
Error **errp) Error **errp)
{ {
/* FIXME: qobject_to_qint mishandles values over INT64_MAX */ /* FIXME: qobject_to_qnum mishandles values over INT64_MAX */
QObjectInputVisitor *qiv = to_qiv(v); QObjectInputVisitor *qiv = to_qiv(v);
QObject *qobj = qobject_input_get_object(qiv, name, true, errp); QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
QInt *qint; QNum *qnum;
int64_t val;
if (!qobj) { if (!qobj) {
return; return;
} }
qint = qobject_to_qint(qobj); qnum = qobject_to_qnum(qobj);
if (!qint) { if (!qnum || !qnum_get_try_int(qnum, &val)) {
error_setg(errp, QERR_INVALID_PARAMETER_TYPE, error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
full_name(qiv, name), "integer"); full_name(qiv, name), "integer");
return;
} }
*obj = val;
*obj = qint_get_int(qint);
} }
static void qobject_input_type_bool(Visitor *v, const char *name, bool *obj, static void qobject_input_type_bool(Visitor *v, const char *name, bool *obj,
@ -428,26 +421,19 @@ static void qobject_input_type_number(Visitor *v, const char *name, double *obj,
{ {
QObjectInputVisitor *qiv = to_qiv(v); QObjectInputVisitor *qiv = to_qiv(v);
QObject *qobj = qobject_input_get_object(qiv, name, true, errp); QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
QInt *qint; QNum *qnum;
QFloat *qfloat;
if (!qobj) { if (!qobj) {
return; return;
} }
qint = qobject_to_qint(qobj); qnum = qobject_to_qnum(qobj);
if (qint) { if (!qnum) {
*obj = qint_get_int(qobject_to_qint(qobj));
return;
}
qfloat = qobject_to_qfloat(qobj);
if (!qfloat) {
error_setg(errp, QERR_INVALID_PARAMETER_TYPE, error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
full_name(qiv, name), "number"); full_name(qiv, name), "number");
return; return;
} }
*obj = qfloat_get_double(qobject_to_qfloat(qobj)); *obj = qnum_get_double(qnum);
} }
static void qobject_input_type_any(Visitor *v, const char *name, QObject **obj, static void qobject_input_type_any(Visitor *v, const char *name, QObject **obj,

View file

@ -147,7 +147,7 @@ static void qobject_output_type_int64(Visitor *v, const char *name, int64_t *obj
Error **errp) Error **errp)
{ {
QObjectOutputVisitor *qov = to_qov(v); 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, static void qobject_output_type_uint64(Visitor *v, const char *name, uint64_t *obj,
@ -155,7 +155,7 @@ static void qobject_output_type_uint64(Visitor *v, const char *name, uint64_t *o
{ {
/* FIXME: QMP outputs values larger than INT64_MAX as negative */ /* FIXME: QMP outputs values larger than INT64_MAX as negative */
QObjectOutputVisitor *qov = to_qov(v); 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_bool(Visitor *v, const char *name, bool *obj, static void qobject_output_type_bool(Visitor *v, const char *name, bool *obj,
@ -180,7 +180,7 @@ static void qobject_output_type_number(Visitor *v, const char *name, double *obj
Error **errp) Error **errp)
{ {
QObjectOutputVisitor *qov = to_qov(v); 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, QObject **obj, static void qobject_output_type_any(Visitor *v, const char *name, QObject **obj,

View file

@ -1 +1 @@
util-obj-y = qint.o qnull.o qobject.o qstring.o qdict.o qlist.o qfloat.o qbool.o util-obj-y = qnull.o qobject.o qstring.o qdict.o qlist.o qbool.o qnum.o

View file

@ -11,8 +11,7 @@
*/ */
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "qapi/qmp/qint.h" #include "qapi/qmp/qnum.h"
#include "qapi/qmp/qfloat.h"
#include "qapi/qmp/qdict.h" #include "qapi/qmp/qdict.h"
#include "qapi/qmp/qbool.h" #include "qapi/qmp/qbool.h"
#include "qapi/qmp/qstring.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' * qdict_get_double(): Get an number mapped by 'key'
* *
* This function assumes that 'key' exists and it stores a * This function assumes that 'key' exists and it stores a QNum.
* QFloat or QInt object.
* *
* Return number mapped by 'key'. * Return number mapped by 'key'.
*/ */
double qdict_get_double(const QDict *qdict, const char *key) double qdict_get_double(const QDict *qdict, const char *key)
{ {
QObject *obj = qdict_get(qdict, key); return qnum_get_double(qobject_to_qnum(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 (double)qint_get_int(qobject_to_qint(obj));
default:
abort();
}
} }
/** /**
* qdict_get_int(): Get an integer mapped by 'key' * qdict_get_int(): Get an integer mapped by 'key'
* *
* This function assumes that 'key' exists and it stores a * This function assumes that 'key' exists and it stores a
* QInt object. * QNum representable as int.
* *
* Return integer mapped by 'key'. * Return integer mapped by 'key'.
*/ */
int64_t qdict_get_int(const QDict *qdict, const char *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' * qdict_get_try_int(): Try to get integer mapped by 'key'
* *
* Return integer mapped by 'key', if it is not present in * Return integer mapped by 'key', if it is not present in the
* the dictionary or if the stored object is not of QInt type * dictionary or if the stored object is not a QNum representing an
* 'def_value' will be returned. * integer, 'def_value' will be returned.
*/ */
int64_t qdict_get_try_int(const QDict *qdict, const char *key, int64_t qdict_get_try_int(const QDict *qdict, const char *key,
int64_t def_value) 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;
return qint ? qint_get_int(qint) : def_value; if (!qnum || !qnum_get_try_int(qnum, &val)) {
return def_value;
}
return val;
} }
/** /**

View file

@ -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));
}

View file

@ -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));
}

159
qemu/qobject/qnum.c Normal file
View file

@ -0,0 +1,159 @@
/*
* 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_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_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_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_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_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));
}

View file

@ -10,19 +10,16 @@
#include "qemu-common.h" #include "qemu-common.h"
#include "qapi/qmp/qbool.h" #include "qapi/qmp/qbool.h"
#include "qapi/qmp/qdict.h" #include "qapi/qmp/qdict.h"
#include "qapi/qmp/qfloat.h"
#include "qapi/qmp/qint.h"
#include "qapi/qmp/qlist.h" #include "qapi/qmp/qlist.h"
#include "qapi/qmp/qstring.h" #include "qapi/qmp/qstring.h"
static void (*qdestroy[QTYPE__MAX])(QObject *) = { static void (*qdestroy[QTYPE__MAX])(QObject *) = {
NULL, /* No such object exists */ NULL, /* No such object exists */
NULL, /* qnull_ is indestructible */ NULL, /* qnull_ is indestructible */
qint_destroy_obj, qnum_destroy_obj,
qstring_destroy_obj, qstring_destroy_obj,
qdict_destroy_obj, qdict_destroy_obj,
qlist_destroy_obj, qlist_destroy_obj,
qfloat_destroy_obj,
qbool_destroy_obj, qbool_destroy_obj,
}; };

View file

@ -24,7 +24,7 @@
#include "qom/qom-qobject.h" #include "qom/qom-qobject.h"
#include "qapi/qmp/qobject.h" #include "qapi/qmp/qobject.h"
#include "qapi/qmp/qbool.h" #include "qapi/qmp/qbool.h"
#include "qapi/qmp/qint.h" #include "qapi/qmp/qnum.h"
#include "qapi/qmp/qstring.h" #include "qapi/qmp/qstring.h"
#include "uc_priv.h" #include "uc_priv.h"
@ -1062,38 +1062,37 @@ bool object_property_get_bool(struct uc_struct *uc, Object *obj, const char *nam
retval = qbool_get_bool(qbool); retval = qbool_get_bool(qbool);
} }
QDECREF(qbool); qobject_decref(ret);
return retval; return retval;
} }
void object_property_set_int(struct uc_struct *uc, Object *obj, int64_t value, void object_property_set_int(struct uc_struct *uc, Object *obj, int64_t value,
const char *name, Error **errp) const char *name, Error **errp)
{ {
QInt *qint = qint_from_int(value); QNum *qnum = qnum_from_int(value);
object_property_set_qobject(uc, obj, QOBJECT(qint), name, errp); object_property_set_qobject(uc, obj, QOBJECT(qnum), name, errp);
QDECREF(qint); QDECREF(qnum);
} }
int64_t object_property_get_int(struct uc_struct *uc, Object *obj, const char *name, int64_t object_property_get_int(struct uc_struct *uc, Object *obj, const char *name,
Error **errp) Error **errp)
{ {
QObject *ret = object_property_get_qobject(uc, obj, name, errp); QObject *ret = object_property_get_qobject(uc, obj, name, errp);
QInt *qint; QNum *qnum;
int64_t retval; int64_t retval;
if (!ret) { if (!ret) {
return -1; 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"); error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "int");
retval = -1; retval = -1;
} else {
retval = qint_get_int(qint);
} }
QDECREF(qint); qobject_decref(ret);
return retval; return retval;
} }

View file

@ -162,7 +162,7 @@ def gen_visit_alternate(name, variants):
ret = '' ret = ''
promote_int = 'true' promote_int = 'true'
for var in variants.variants: for var in variants.variants:
if var.type.alternate_qtype() == 'QTYPE_QINT': if var.type.alternate_qtype() == 'QTYPE_QNUM':
promote_int = 'false' promote_int = 'false'
ret += mcgen(''' ret += mcgen('''

View file

@ -21,18 +21,18 @@ import string
builtin_types = { builtin_types = {
'str': 'QTYPE_QSTRING', 'str': 'QTYPE_QSTRING',
'int': 'QTYPE_QINT', 'int': 'QTYPE_QNUM',
'number': 'QTYPE_QFLOAT', 'number': 'QTYPE_QNUM',
'bool': 'QTYPE_QBOOL', 'bool': 'QTYPE_QBOOL',
'int8': 'QTYPE_QINT', 'int8': 'QTYPE_QNUM',
'int16': 'QTYPE_QINT', 'int16': 'QTYPE_QNUM',
'int32': 'QTYPE_QINT', 'int32': 'QTYPE_QNUM',
'int64': 'QTYPE_QINT', 'int64': 'QTYPE_QNUM',
'uint8': 'QTYPE_QINT', 'uint8': 'QTYPE_QNUM',
'uint16': 'QTYPE_QINT', 'uint16': 'QTYPE_QNUM',
'uint32': 'QTYPE_QINT', 'uint32': 'QTYPE_QNUM',
'uint64': 'QTYPE_QINT', 'uint64': 'QTYPE_QNUM',
'size': 'QTYPE_QINT', 'size': 'QTYPE_QNUM',
'any': None, # any QType possible, actually 'any': None, # any QType possible, actually
'QType': 'QTYPE_QSTRING', 'QType': 'QTYPE_QSTRING',
} }
@ -870,8 +870,8 @@ class QAPISchemaType(QAPISchemaEntity):
def alternate_qtype(self): def alternate_qtype(self):
json2qtype = { json2qtype = {
'string': 'QTYPE_QSTRING', 'string': 'QTYPE_QSTRING',
'number': 'QTYPE_QFLOAT', 'number': 'QTYPE_QNUM',
'int': 'QTYPE_QINT', 'int': 'QTYPE_QNUM',
'boolean': 'QTYPE_QBOOL', 'boolean': 'QTYPE_QBOOL',
'object': 'QTYPE_QDICT' 'object': 'QTYPE_QDICT'
} }
@ -1319,9 +1319,9 @@ class QAPISchema(object):
self.the_empty_object_type = QAPISchemaObjectType('q_empty', None, self.the_empty_object_type = QAPISchemaObjectType('q_empty', None,
None, [], None) None, [], None)
self._def_entity(self.the_empty_object_type) self._def_entity(self.the_empty_object_type)
qtype_values = self._make_enum_members(['none', 'qnull', 'qint', qtype_values = self._make_enum_members(['none', 'qnull', 'qnum',
'qstring', 'qdict', 'qlist', 'qstring', 'qdict', 'qlist',
'qfloat', 'qbool']) 'qbool'])
self._def_entity(QAPISchemaEnumType('QType', None, qtype_values, self._def_entity(QAPISchemaEnumType('QType', None, qtype_values,
'QTYPE')) 'QTYPE'))