qapi: Introduce a first class 'null' type
I expect the 'null' type to be useful mostly for members of alternate types. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Daniel P. Berrange <berrange@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
This commit is contained in:
parent
d2f95f4d48
commit
4d2d5c41a9
|
@ -282,6 +282,7 @@ The following types are predefined, and map to C as follows:
|
||||||
size uint64_t like uint64_t, except StringInputVisitor
|
size uint64_t like uint64_t, except StringInputVisitor
|
||||||
accepts size suffixes
|
accepts size suffixes
|
||||||
bool bool JSON true or false
|
bool bool JSON true or false
|
||||||
|
null QNull * JSON null
|
||||||
any QObject * any JSON value
|
any QObject * any JSON value
|
||||||
QType QType JSON string matching enum QType values
|
QType QType JSON string matching enum QType values
|
||||||
|
|
||||||
|
@ -536,10 +537,11 @@ can only express a choice between types represented differently in
|
||||||
JSON. If a branch is typed as the 'bool' built-in, the alternate
|
JSON. If a branch is typed as the 'bool' built-in, the alternate
|
||||||
accepts true and false; if it is typed as any of the various numeric
|
accepts true and false; if it is typed as any of the various numeric
|
||||||
built-ins, it accepts a JSON number; if it is typed as a 'str'
|
built-ins, it accepts a JSON number; if it is typed as a 'str'
|
||||||
built-in or named enum type, it accepts a JSON string; and if it is
|
built-in or named enum type, it accepts a JSON string; if it is typed
|
||||||
typed as a complex type (struct or union), it accepts a JSON object.
|
as the 'null' built-in, it accepts JSON null; and if it is typed as a
|
||||||
Two different complex types, for instance, aren't permitted, because
|
complex type (struct or union), it accepts a JSON object. Two
|
||||||
both are represented as a JSON object.
|
different complex types, for instance, aren't permitted, because both
|
||||||
|
are represented as a JSON object.
|
||||||
|
|
||||||
The example alternate declaration above allows using both of the
|
The example alternate declaration above allows using both of the
|
||||||
following example objects:
|
following example objects:
|
||||||
|
|
|
@ -93,9 +93,9 @@ static inline QType qobject_type(const QObject *obj)
|
||||||
return obj->type;
|
return obj->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct QNull {
|
struct QNull {
|
||||||
QObject base;
|
QObject base;
|
||||||
} QNull;
|
};
|
||||||
|
|
||||||
extern QNull qnull_;
|
extern QNull qnull_;
|
||||||
|
|
||||||
|
|
|
@ -89,6 +89,7 @@ typedef struct QEMUSGList QEMUSGList;
|
||||||
typedef struct QEMUTimer QEMUTimer;
|
typedef struct QEMUTimer QEMUTimer;
|
||||||
typedef struct QEMUTimerListGroup QEMUTimerListGroup;
|
typedef struct QEMUTimerListGroup QEMUTimerListGroup;
|
||||||
typedef struct QObject QObject;
|
typedef struct QObject QObject;
|
||||||
|
typedef struct QNull QNull;
|
||||||
typedef struct RAMBlock RAMBlock;
|
typedef struct RAMBlock RAMBlock;
|
||||||
typedef struct Range Range;
|
typedef struct Range Range;
|
||||||
typedef struct SerialState SerialState;
|
typedef struct SerialState SerialState;
|
||||||
|
|
|
@ -20,6 +20,7 @@ import sys
|
||||||
from ordereddict import OrderedDict
|
from ordereddict import OrderedDict
|
||||||
|
|
||||||
builtin_types = {
|
builtin_types = {
|
||||||
|
'null': 'QTYPE_QNULL',
|
||||||
'str': 'QTYPE_QSTRING',
|
'str': 'QTYPE_QSTRING',
|
||||||
'int': 'QTYPE_QNUM',
|
'int': 'QTYPE_QNUM',
|
||||||
'number': 'QTYPE_QNUM',
|
'number': 'QTYPE_QNUM',
|
||||||
|
@ -1056,6 +1057,7 @@ class QAPISchemaType(QAPISchemaEntity):
|
||||||
|
|
||||||
def alternate_qtype(self):
|
def alternate_qtype(self):
|
||||||
json2qtype = {
|
json2qtype = {
|
||||||
|
'null': 'QTYPE_QNULL',
|
||||||
'string': 'QTYPE_QSTRING',
|
'string': 'QTYPE_QSTRING',
|
||||||
'number': 'QTYPE_QNUM',
|
'number': 'QTYPE_QNUM',
|
||||||
'int': 'QTYPE_QNUM',
|
'int': 'QTYPE_QNUM',
|
||||||
|
@ -1515,7 +1517,8 @@ class QAPISchema(object):
|
||||||
('uint64', 'int', 'uint64_t'),
|
('uint64', 'int', 'uint64_t'),
|
||||||
('size', 'int', 'uint64_t'),
|
('size', 'int', 'uint64_t'),
|
||||||
('bool', 'boolean', 'bool'),
|
('bool', 'boolean', 'bool'),
|
||||||
('any', 'value', 'QObject' + pointer_suffix)]:
|
('any', 'value', 'QObject' + pointer_suffix),
|
||||||
|
('null', 'null', 'QNull' + pointer_suffix)]:
|
||||||
self._def_builtin_type(*t)
|
self._def_builtin_type(*t)
|
||||||
self.the_empty_object_type = QAPISchemaObjectType(
|
self.the_empty_object_type = QAPISchemaObjectType(
|
||||||
'q_empty', None, None, None, [], None)
|
'q_empty', None, None, None, [], None)
|
||||||
|
|
|
@ -93,7 +93,8 @@
|
||||||
{ 'struct': 'WrapAlternate',
|
{ 'struct': 'WrapAlternate',
|
||||||
'data': { 'alt': 'UserDefAlternate' } }
|
'data': { 'alt': 'UserDefAlternate' } }
|
||||||
{ 'alternate': 'UserDefAlternate',
|
{ 'alternate': 'UserDefAlternate',
|
||||||
'data': { 'udfu': 'UserDefFlatUnion', 'e': 'EnumOne', 'i': 'int' } }
|
'data': { 'udfu': 'UserDefFlatUnion', 'e': 'EnumOne', 'i': 'int',
|
||||||
|
'n': 'null' } }
|
||||||
|
|
||||||
{ 'struct': 'UserDefC',
|
{ 'struct': 'UserDefC',
|
||||||
'data': { 'string1': 'str', 'string2': 'str' } }
|
'data': { 'string1': 'str', 'string2': 'str' } }
|
||||||
|
|
|
@ -64,6 +64,7 @@ alternate UserDefAlternate
|
||||||
case udfu: UserDefFlatUnion
|
case udfu: UserDefFlatUnion
|
||||||
case e: EnumOne
|
case e: EnumOne
|
||||||
case i: int
|
case i: int
|
||||||
|
case n: null
|
||||||
object UserDefB
|
object UserDefB
|
||||||
member intb: int optional=False
|
member intb: int optional=False
|
||||||
member a-b: bool optional=True
|
member a-b: bool optional=True
|
||||||
|
|
|
@ -583,6 +583,11 @@ static void test_visitor_in_alternate(TestInputVisitorData *data,
|
||||||
g_assert_cmpint(tmp->u.e, ==, ENUM_ONE_VALUE1);
|
g_assert_cmpint(tmp->u.e, ==, ENUM_ONE_VALUE1);
|
||||||
qapi_free_UserDefAlternate(tmp);
|
qapi_free_UserDefAlternate(tmp);
|
||||||
|
|
||||||
|
v = visitor_input_test_init(data, "null");
|
||||||
|
visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
|
||||||
|
g_assert_cmpint(tmp->type, ==, QTYPE_QNULL);
|
||||||
|
qapi_free_UserDefAlternate(tmp);
|
||||||
|
|
||||||
v = visitor_input_test_init(data, "{'integer':1, 'string':'str', "
|
v = visitor_input_test_init(data, "{'integer':1, 'string':'str', "
|
||||||
"'enum1':'value1', 'boolean':true}");
|
"'enum1':'value1', 'boolean':true}");
|
||||||
visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
|
visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort);
|
||||||
|
|
|
@ -422,6 +422,16 @@ static void test_visitor_out_alternate(TestOutputVisitorData *data,
|
||||||
|
|
||||||
qapi_free_UserDefAlternate(tmp);
|
qapi_free_UserDefAlternate(tmp);
|
||||||
|
|
||||||
|
visitor_reset(data);
|
||||||
|
tmp = g_new0(UserDefAlternate, 1);
|
||||||
|
tmp->type = QTYPE_QNULL;
|
||||||
|
tmp->u.n = qnull();
|
||||||
|
|
||||||
|
visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort);
|
||||||
|
g_assert_cmpint(qobject_type(visitor_get(data)), ==, QTYPE_QNULL);
|
||||||
|
|
||||||
|
qapi_free_UserDefAlternate(tmp);
|
||||||
|
|
||||||
visitor_reset(data);
|
visitor_reset(data);
|
||||||
tmp = g_new0(UserDefAlternate, 1);
|
tmp = g_new0(UserDefAlternate, 1);
|
||||||
tmp->type = QTYPE_QDICT;
|
tmp->type = QTYPE_QDICT;
|
||||||
|
|
Loading…
Reference in New Issue