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.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20170607163635.17635-7-marcandre.lureau@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
[parse_stats_intervals() simplified a bit, comment in
test_visitor_in_int_overflow() tidied up, suppress bogus warnings]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
This commit is contained in:
Marc-André Lureau 2017-06-07 20:35:58 +04:00 committed by Markus Armbruster
parent 58634047b7
commit 01b2ffcedd
65 changed files with 630 additions and 664 deletions

View file

@ -886,21 +886,23 @@ 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);
}
}
@ -921,12 +923,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 +938,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 +1023,7 @@ struct LiteralQObject
{
int type;
union {
int64_t qint;
int64_t qnum;
const char *qstr;
LiteralQDictEntry *qdict;
LiteralQObject *qlist;
@ -1032,7 +1036,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 +1068,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 +1121,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 +1133,7 @@ static void simple_dict(void)
}, {
.encoded = "{\"foo\": 43}",
.decoded = QLIT_QDICT(((LiteralQDictEntry[]){
{ "foo", QLIT_QINT(43) },
{ "foo", QLIT_QNUM(43) },
{ }
})),
},
@ -1212,15 +1219,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 +1276,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 +1334,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),
{}})),
{}}));