mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-05 16:53:55 -06:00
QAPI patches patches for 2021-09-25
-----BEGIN PGP SIGNATURE----- iQJGBAABCAAwFiEENUvIs9frKmtoZ05fOHC0AOuRhlMFAmFRvKcSHGFybWJydUBy ZWRoYXQuY29tAAoJEDhwtADrkYZTSRIQAJcuW3eCoQ3moFa8e/nDoWnkW75eSfO4 4T3EuW5Y9ODzfShtagKEeCX0oWAVDJM+vfbLNYk+e12kPiDVUmmiMw1urWmFI658 la4KgKnV55BJ1xCvl58F1WAfQ7UMIFDEMksq61qZUOnYwj3JEKhqkn7ztUC+HaGi uMR2EzTa89+RzDavSXpGfONAnV5pzKtEh5WnkSM+dIRD4HjsaYDa77j1d5D5TGIR hiD/YT/QFo0eSF0sFyIbuRrPfMkUiqymaEFBS7OB5vOM4nSPrjoEpTWCOFVdD78D iruN90xvQFAj8mD5N3GZsq5jcv2JLVExNPs23qNNXzHgOmGWdCWZ8RC857bLJpl3 ToF2SYQqQiv/pdXnOg9ODaEUuepyGxWsr98H2zCKYi19lTamZFr6KZO80UgoTFMi 2FfBJTM0z0uR1aFNl0BcR/qRZlCuPWTrjwdHqXjtzgs6y0Ycfvy1EDmwkndS43uk NH3IEScsf5pL8I2YYSIROfcrhNKO/KHMeWtXZFEVLVHCRi4waOb523lFEqm3YgYl Wsa8VgxWt7XoXqp3/nQhvg/OmMw5eZuFgEgQEN7h9gvJHbXQqy/Du40UVuTVxDiH InjDe3A24BiIBf2mA/b8wEwd2u/bTWcl2vysq0nXB0oipfnnksjafvLkOTP+ebTs LQ3u2NyptUTz =ApRW -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2021-09-25-v2' into staging QAPI patches patches for 2021-09-25 # gpg: Signature made Mon 27 Sep 2021 13:44:23 BST # gpg: using RSA key 354BC8B3D7EB2A6B68674E5F3870B400EB918653 # gpg: issuer "armbru@redhat.com" # gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" [full] # gpg: aka "Markus Armbruster <armbru@pond.sub.org>" [full] # Primary key fingerprint: 354B C8B3 D7EB 2A6B 6867 4E5F 3870 B400 EB91 8653 * remotes/armbru/tags/pull-qapi-2021-09-25-v2: (25 commits) tests/qapi-schema: Make test-qapi.py -u work when files are absent tests/qapi-schema: Use Python OSError instead of outmoded IOError test-clone-visitor: Correct an accidental rename tests/qapi-schema: Rename flat-union-* test cases to union-* qapi: Drop simple unions tests/qapi-schema: Purge simple unions from tests tests/qapi-schema: Drop simple union __org.qemu_x-Union1 test-clone-visitor: Wean off __org.qemu_x-Union1 tests/qapi-schema: Rewrite simple union TestIfUnion to be flat tests/qapi-schema: Simple union UserDefListUnion is now unused, drop tests/qapi-schema: Wean off UserDefListUnion test-clone-visitor: Wean off UserDefListUnion test-qobject-output-visitor: Wean off UserDefListUnion test-qobject-input-visitor: Wean off UserDefListUnion tests/qapi-schema: Prepare for simple union UserDefListUnion removal qapi: Convert simple union TransactionAction to flat one qapi: Convert simple union ImageInfoSpecific to flat one qapi: Convert simple union SocketAddressLegacy to flat one qapi: Convert simple union ChardevBackend to flat one qapi: Convert simple union MemoryDeviceInfo to flat one ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
de8ed1055c
118 changed files with 1038 additions and 1228 deletions
|
@ -623,7 +623,7 @@ static TpmTypeOptions *tpm_emulator_get_tpm_options(TPMBackend *tb)
|
||||||
TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
|
TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
|
||||||
TpmTypeOptions *options = g_new0(TpmTypeOptions, 1);
|
TpmTypeOptions *options = g_new0(TpmTypeOptions, 1);
|
||||||
|
|
||||||
options->type = TPM_TYPE_OPTIONS_KIND_EMULATOR;
|
options->type = TPM_TYPE_EMULATOR;
|
||||||
options->u.emulator.data = QAPI_CLONE(TPMEmulatorOptions, tpm_emu->options);
|
options->u.emulator.data = QAPI_CLONE(TPMEmulatorOptions, tpm_emu->options);
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
|
|
|
@ -321,7 +321,7 @@ static TpmTypeOptions *tpm_passthrough_get_tpm_options(TPMBackend *tb)
|
||||||
{
|
{
|
||||||
TpmTypeOptions *options = g_new0(TpmTypeOptions, 1);
|
TpmTypeOptions *options = g_new0(TpmTypeOptions, 1);
|
||||||
|
|
||||||
options->type = TPM_TYPE_OPTIONS_KIND_PASSTHROUGH;
|
options->type = TPM_TYPE_PASSTHROUGH;
|
||||||
options->u.passthrough.data = QAPI_CLONE(TPMPassthroughOptions,
|
options->u.passthrough.data = QAPI_CLONE(TPMPassthroughOptions,
|
||||||
TPM_PASSTHROUGH(tb)->options);
|
TPM_PASSTHROUGH(tb)->options);
|
||||||
|
|
||||||
|
|
|
@ -1520,7 +1520,7 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
|
||||||
addr = g_new0(SocketAddressLegacy, 1);
|
addr = g_new0(SocketAddressLegacy, 1);
|
||||||
if (path) {
|
if (path) {
|
||||||
UnixSocketAddress *q_unix;
|
UnixSocketAddress *q_unix;
|
||||||
addr->type = SOCKET_ADDRESS_LEGACY_KIND_UNIX;
|
addr->type = SOCKET_ADDRESS_TYPE_UNIX;
|
||||||
q_unix = addr->u.q_unix.data = g_new0(UnixSocketAddress, 1);
|
q_unix = addr->u.q_unix.data = g_new0(UnixSocketAddress, 1);
|
||||||
q_unix->path = g_strdup(path);
|
q_unix->path = g_strdup(path);
|
||||||
#ifdef CONFIG_LINUX
|
#ifdef CONFIG_LINUX
|
||||||
|
@ -1530,7 +1530,7 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
|
||||||
q_unix->abstract = abstract;
|
q_unix->abstract = abstract;
|
||||||
#endif
|
#endif
|
||||||
} else if (host) {
|
} else if (host) {
|
||||||
addr->type = SOCKET_ADDRESS_LEGACY_KIND_INET;
|
addr->type = SOCKET_ADDRESS_TYPE_INET;
|
||||||
addr->u.inet.data = g_new(InetSocketAddress, 1);
|
addr->u.inet.data = g_new(InetSocketAddress, 1);
|
||||||
*addr->u.inet.data = (InetSocketAddress) {
|
*addr->u.inet.data = (InetSocketAddress) {
|
||||||
.host = g_strdup(host),
|
.host = g_strdup(host),
|
||||||
|
@ -1543,7 +1543,7 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
|
||||||
.ipv6 = qemu_opt_get_bool(opts, "ipv6", 0),
|
.ipv6 = qemu_opt_get_bool(opts, "ipv6", 0),
|
||||||
};
|
};
|
||||||
} else if (fd) {
|
} else if (fd) {
|
||||||
addr->type = SOCKET_ADDRESS_LEGACY_KIND_FD;
|
addr->type = SOCKET_ADDRESS_TYPE_FD;
|
||||||
addr->u.fd.data = g_new(String, 1);
|
addr->u.fd.data = g_new(String, 1);
|
||||||
addr->u.fd.data->str = g_strdup(fd);
|
addr->u.fd.data->str = g_strdup(fd);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -165,7 +165,7 @@ static void qemu_chr_parse_udp(QemuOpts *opts, ChardevBackend *backend,
|
||||||
qemu_chr_parse_common(opts, qapi_ChardevUdp_base(udp));
|
qemu_chr_parse_common(opts, qapi_ChardevUdp_base(udp));
|
||||||
|
|
||||||
addr = g_new0(SocketAddressLegacy, 1);
|
addr = g_new0(SocketAddressLegacy, 1);
|
||||||
addr->type = SOCKET_ADDRESS_LEGACY_KIND_INET;
|
addr->type = SOCKET_ADDRESS_TYPE_INET;
|
||||||
addr->u.inet.data = g_new(InetSocketAddress, 1);
|
addr->u.inet.data = g_new(InetSocketAddress, 1);
|
||||||
*addr->u.inet.data = (InetSocketAddress) {
|
*addr->u.inet.data = (InetSocketAddress) {
|
||||||
.host = g_strdup(host),
|
.host = g_strdup(host),
|
||||||
|
@ -180,7 +180,7 @@ static void qemu_chr_parse_udp(QemuOpts *opts, ChardevBackend *backend,
|
||||||
if (has_local) {
|
if (has_local) {
|
||||||
udp->has_local = true;
|
udp->has_local = true;
|
||||||
addr = g_new0(SocketAddressLegacy, 1);
|
addr = g_new0(SocketAddressLegacy, 1);
|
||||||
addr->type = SOCKET_ADDRESS_LEGACY_KIND_INET;
|
addr->type = SOCKET_ADDRESS_TYPE_INET;
|
||||||
addr->u.inet.data = g_new(InetSocketAddress, 1);
|
addr->u.inet.data = g_new(InetSocketAddress, 1);
|
||||||
*addr->u.inet.data = (InetSocketAddress) {
|
*addr->u.inet.data = (InetSocketAddress) {
|
||||||
.host = g_strdup(localaddr),
|
.host = g_strdup(localaddr),
|
||||||
|
|
|
@ -319,13 +319,9 @@ Union types
|
||||||
Syntax::
|
Syntax::
|
||||||
|
|
||||||
UNION = { 'union': STRING,
|
UNION = { 'union': STRING,
|
||||||
'data': BRANCHES,
|
|
||||||
'*if': COND,
|
|
||||||
'*features': FEATURES }
|
|
||||||
| { 'union': STRING,
|
|
||||||
'data': BRANCHES,
|
|
||||||
'base': ( MEMBERS | STRING ),
|
'base': ( MEMBERS | STRING ),
|
||||||
'discriminator': STRING,
|
'discriminator': STRING,
|
||||||
|
'data': BRANCHES,
|
||||||
'*if': COND,
|
'*if': COND,
|
||||||
'*features': FEATURES }
|
'*features': FEATURES }
|
||||||
BRANCHES = { BRANCH, ... }
|
BRANCHES = { BRANCH, ... }
|
||||||
|
@ -334,63 +330,30 @@ Syntax::
|
||||||
|
|
||||||
Member 'union' names the union type.
|
Member 'union' names the union type.
|
||||||
|
|
||||||
There are two flavors of union types: simple (no discriminator or
|
|
||||||
base), and flat (both discriminator and base).
|
|
||||||
|
|
||||||
Each BRANCH of the 'data' object defines a branch of the union. A
|
|
||||||
union must have at least one branch.
|
|
||||||
|
|
||||||
The BRANCH's STRING name is the branch name.
|
|
||||||
|
|
||||||
The BRANCH's value defines the branch's properties, in particular its
|
|
||||||
type. The form TYPE-REF_ is shorthand for :code:`{ 'type': TYPE-REF }`.
|
|
||||||
|
|
||||||
A simple union type defines a mapping from automatic discriminator
|
|
||||||
values to data types like in this example::
|
|
||||||
|
|
||||||
{ 'struct': 'BlockdevOptionsFile', 'data': { 'filename': 'str' } }
|
|
||||||
{ 'struct': 'BlockdevOptionsQcow2',
|
|
||||||
'data': { 'backing': 'str', '*lazy-refcounts': 'bool' } }
|
|
||||||
|
|
||||||
{ 'union': 'BlockdevOptionsSimple',
|
|
||||||
'data': { 'file': 'BlockdevOptionsFile',
|
|
||||||
'qcow2': 'BlockdevOptionsQcow2' } }
|
|
||||||
|
|
||||||
In the Client JSON Protocol, a simple union is represented by an
|
|
||||||
object that contains the 'type' member as a discriminator, and a
|
|
||||||
'data' member that is of the specified data type corresponding to the
|
|
||||||
discriminator value, as in these examples::
|
|
||||||
|
|
||||||
{ "type": "file", "data": { "filename": "/some/place/my-image" } }
|
|
||||||
{ "type": "qcow2", "data": { "backing": "/some/place/my-image",
|
|
||||||
"lazy-refcounts": true } }
|
|
||||||
|
|
||||||
The generated C code uses a struct containing a union. Additionally,
|
|
||||||
an implicit C enum 'NameKind' is created, corresponding to the union
|
|
||||||
'Name', for accessing the various branches of the union. The value
|
|
||||||
for each branch can be of any type.
|
|
||||||
|
|
||||||
Flat unions permit arbitrary common members that occur in all variants
|
|
||||||
of the union, not just a discriminator. Their discriminators need not
|
|
||||||
be named 'type'. They also avoid nesting on the wire.
|
|
||||||
|
|
||||||
The 'base' member defines the common members. If it is a MEMBERS_
|
The 'base' member defines the common members. If it is a MEMBERS_
|
||||||
object, it defines common members just like a struct type's 'data'
|
object, it defines common members just like a struct type's 'data'
|
||||||
member defines struct type members. If it is a STRING, it names a
|
member defines struct type members. If it is a STRING, it names a
|
||||||
struct type whose members are the common members.
|
struct type whose members are the common members.
|
||||||
|
|
||||||
All flat union branches must be `Struct types`_.
|
Member 'discriminator' must name a non-optional enum-typed member of
|
||||||
|
the base struct. That member's value selects a branch by its name.
|
||||||
|
If no such branch exists, an empty branch is assumed.
|
||||||
|
|
||||||
In the Client JSON Protocol, a flat union is represented by an object
|
Each BRANCH of the 'data' object defines a branch of the union. A
|
||||||
with the common members (from the base type) and the selected branch's
|
union must have at least one branch.
|
||||||
members. The two sets of member names must be disjoint. Member
|
|
||||||
'discriminator' must name a non-optional enum-typed member of the base
|
|
||||||
struct.
|
|
||||||
|
|
||||||
The following example enhances the above simple union example by
|
The BRANCH's STRING name is the branch name. It must be a value of
|
||||||
adding an optional common member 'read-only', renaming the
|
the discriminator enum type.
|
||||||
discriminator to something more applicable than the simple union's
|
|
||||||
default of 'type', and reducing the number of ``{}`` required on the wire::
|
The BRANCH's value defines the branch's properties, in particular its
|
||||||
|
type. The type must a struct type. The form TYPE-REF_ is shorthand
|
||||||
|
for :code:`{ 'type': TYPE-REF }`.
|
||||||
|
|
||||||
|
In the Client JSON Protocol, a union is represented by an object with
|
||||||
|
the common members (from the base type) and the selected branch's
|
||||||
|
members. The two sets of member names must be disjoint.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
{ 'enum': 'BlockdevDriver', 'data': [ 'file', 'qcow2' ] }
|
{ 'enum': 'BlockdevDriver', 'data': [ 'file', 'qcow2' ] }
|
||||||
{ 'union': 'BlockdevOptions',
|
{ 'union': 'BlockdevOptions',
|
||||||
|
@ -406,30 +369,11 @@ Resulting in these JSON objects::
|
||||||
{ "driver": "qcow2", "read-only": false,
|
{ "driver": "qcow2", "read-only": false,
|
||||||
"backing": "/some/place/my-image", "lazy-refcounts": true }
|
"backing": "/some/place/my-image", "lazy-refcounts": true }
|
||||||
|
|
||||||
Notice that in a flat union, the discriminator name is controlled by
|
The order of branches need not match the order of the enum values.
|
||||||
the user, but because it must map to a base member with enum type, the
|
The branches need not cover all possible enum values. In the
|
||||||
code generator ensures that branches match the existing values of the
|
resulting generated C data types, a union is represented as a struct
|
||||||
enum. The order of branches need not match the order of the enum
|
with the base members in QAPI schema order, and then a union of
|
||||||
values. The branches need not cover all possible enum values.
|
structures for each branch of the struct.
|
||||||
Omitted enum values are still valid branches that add no additional
|
|
||||||
members to the data type. In the resulting generated C data types, a
|
|
||||||
flat union is represented as a struct with the base members in QAPI
|
|
||||||
schema order, and then a union of structures for each branch of the
|
|
||||||
struct.
|
|
||||||
|
|
||||||
A simple union can always be re-written as a flat union where the base
|
|
||||||
class has a single member named 'type', and where each branch of the
|
|
||||||
union has a struct with a single member named 'data'. That is, ::
|
|
||||||
|
|
||||||
{ 'union': 'Simple', 'data': { 'one': 'str', 'two': 'int' } }
|
|
||||||
|
|
||||||
is identical on the wire to::
|
|
||||||
|
|
||||||
{ 'enum': 'Enum', 'data': ['one', 'two'] }
|
|
||||||
{ 'struct': 'Branch1', 'data': { 'data': 'str' } }
|
|
||||||
{ 'struct': 'Branch2', 'data': { 'data': 'int' } }
|
|
||||||
{ 'union': 'Flat', 'base': { 'type': 'Enum' }, 'discriminator': 'type',
|
|
||||||
'data': { 'one': 'Branch1', 'two': 'Branch2' } }
|
|
||||||
|
|
||||||
The optional 'if' member specifies a conditional. See `Configuring
|
The optional 'if' member specifies a conditional. See `Configuring
|
||||||
the schema`_ below for more on this.
|
the schema`_ below for more on this.
|
||||||
|
@ -859,9 +803,9 @@ longhand form of MEMBER.
|
||||||
Example: a struct type with unconditional member 'foo' and conditional
|
Example: a struct type with unconditional member 'foo' and conditional
|
||||||
member 'bar' ::
|
member 'bar' ::
|
||||||
|
|
||||||
{ 'struct': 'IfStruct', 'data':
|
{ 'struct': 'IfStruct',
|
||||||
{ 'foo': 'int',
|
'data': { 'foo': 'int',
|
||||||
'bar': { 'type': 'int', 'if': 'IFCOND'} } }
|
'bar': { 'type': 'int', 'if': 'IFCOND'} } }
|
||||||
|
|
||||||
A union's discriminator may not be conditional.
|
A union's discriminator may not be conditional.
|
||||||
|
|
||||||
|
@ -871,9 +815,9 @@ the longhand form of ENUM-VALUE_.
|
||||||
Example: an enum type with unconditional value 'foo' and conditional
|
Example: an enum type with unconditional value 'foo' and conditional
|
||||||
value 'bar' ::
|
value 'bar' ::
|
||||||
|
|
||||||
{ 'enum': 'IfEnum', 'data':
|
{ 'enum': 'IfEnum',
|
||||||
[ 'foo',
|
'data': [ 'foo',
|
||||||
{ 'name' : 'bar', 'if': 'IFCOND' } ] }
|
{ 'name' : 'bar', 'if': 'IFCOND' } ] }
|
||||||
|
|
||||||
Likewise, features can be conditional. This requires the longhand
|
Likewise, features can be conditional. This requires the longhand
|
||||||
form of FEATURE_.
|
form of FEATURE_.
|
||||||
|
@ -1246,7 +1190,7 @@ that provides the variant members for this type tag value). The
|
||||||
"variants" array is in no particular order, and is not guaranteed to
|
"variants" array is in no particular order, and is not guaranteed to
|
||||||
list cases in the same order as the corresponding "tag" enum type.
|
list cases in the same order as the corresponding "tag" enum type.
|
||||||
|
|
||||||
Example: the SchemaInfo for flat union BlockdevOptions from section
|
Example: the SchemaInfo for union BlockdevOptions from section
|
||||||
`Union types`_ ::
|
`Union types`_ ::
|
||||||
|
|
||||||
{ "name": "BlockdevOptions", "meta-type": "object",
|
{ "name": "BlockdevOptions", "meta-type": "object",
|
||||||
|
@ -1261,27 +1205,6 @@ Example: the SchemaInfo for flat union BlockdevOptions from section
|
||||||
Note that base types are "flattened": its members are included in the
|
Note that base types are "flattened": its members are included in the
|
||||||
"members" array.
|
"members" array.
|
||||||
|
|
||||||
A simple union implicitly defines an enumeration type for its implicit
|
|
||||||
discriminator (called "type" on the wire, see section `Union types`_).
|
|
||||||
|
|
||||||
A simple union implicitly defines an object type for each of its
|
|
||||||
variants.
|
|
||||||
|
|
||||||
Example: the SchemaInfo for simple union BlockdevOptionsSimple from section
|
|
||||||
`Union types`_ ::
|
|
||||||
|
|
||||||
{ "name": "BlockdevOptionsSimple", "meta-type": "object",
|
|
||||||
"members": [
|
|
||||||
{ "name": "type", "type": "BlockdevOptionsSimpleKind" } ],
|
|
||||||
"tag": "type",
|
|
||||||
"variants": [
|
|
||||||
{ "case": "file", "type": "q_obj-BlockdevOptionsFile-wrapper" },
|
|
||||||
{ "case": "qcow2", "type": "q_obj-BlockdevOptionsQcow2-wrapper" } ] }
|
|
||||||
|
|
||||||
Enumeration type "BlockdevOptionsSimpleKind" and the object types
|
|
||||||
"q_obj-BlockdevOptionsFile-wrapper", "q_obj-BlockdevOptionsQcow2-wrapper"
|
|
||||||
are implicitly defined.
|
|
||||||
|
|
||||||
The SchemaInfo for an alternate type has meta-type "alternate", and
|
The SchemaInfo for an alternate type has meta-type "alternate", and
|
||||||
variant member "members". "members" is a JSON array. Each element is
|
variant member "members". "members" is a JSON array. Each element is
|
||||||
a JSON object with member "type", which names a type. Values of the
|
a JSON object with member "type", which names a type. Values of the
|
||||||
|
|
|
@ -925,10 +925,10 @@ void hmp_info_tpm(Monitor *mon, const QDict *qdict)
|
||||||
c, TpmModel_str(ti->model));
|
c, TpmModel_str(ti->model));
|
||||||
|
|
||||||
monitor_printf(mon, " \\ %s: type=%s",
|
monitor_printf(mon, " \\ %s: type=%s",
|
||||||
ti->id, TpmTypeOptionsKind_str(ti->options->type));
|
ti->id, TpmType_str(ti->options->type));
|
||||||
|
|
||||||
switch (ti->options->type) {
|
switch (ti->options->type) {
|
||||||
case TPM_TYPE_OPTIONS_KIND_PASSTHROUGH:
|
case TPM_TYPE_PASSTHROUGH:
|
||||||
tpo = ti->options->u.passthrough.data;
|
tpo = ti->options->u.passthrough.data;
|
||||||
monitor_printf(mon, "%s%s%s%s",
|
monitor_printf(mon, "%s%s%s%s",
|
||||||
tpo->has_path ? ",path=" : "",
|
tpo->has_path ? ",path=" : "",
|
||||||
|
@ -936,11 +936,11 @@ void hmp_info_tpm(Monitor *mon, const QDict *qdict)
|
||||||
tpo->has_cancel_path ? ",cancel-path=" : "",
|
tpo->has_cancel_path ? ",cancel-path=" : "",
|
||||||
tpo->has_cancel_path ? tpo->cancel_path : "");
|
tpo->has_cancel_path ? tpo->cancel_path : "");
|
||||||
break;
|
break;
|
||||||
case TPM_TYPE_OPTIONS_KIND_EMULATOR:
|
case TPM_TYPE_EMULATOR:
|
||||||
teo = ti->options->u.emulator.data;
|
teo = ti->options->u.emulator.data;
|
||||||
monitor_printf(mon, ",chardev=%s", teo->chardev);
|
monitor_printf(mon, ",chardev=%s", teo->chardev);
|
||||||
break;
|
break;
|
||||||
case TPM_TYPE_OPTIONS_KIND__MAX:
|
case TPM_TYPE__MAX:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
monitor_printf(mon, "\n");
|
monitor_printf(mon, "\n");
|
||||||
|
|
|
@ -139,6 +139,52 @@
|
||||||
'*encryption-format': 'RbdImageEncryptionFormat'
|
'*encryption-format': 'RbdImageEncryptionFormat'
|
||||||
} }
|
} }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @ImageInfoSpecificKind:
|
||||||
|
#
|
||||||
|
# @luks: Since 2.7
|
||||||
|
# @rbd: Since 6.1
|
||||||
|
#
|
||||||
|
# Since: 1.7
|
||||||
|
##
|
||||||
|
{ 'enum': 'ImageInfoSpecificKind',
|
||||||
|
'data': [ 'qcow2', 'vmdk', 'luks', 'rbd' ] }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @ImageInfoSpecificQCow2Wrapper:
|
||||||
|
#
|
||||||
|
# Since: 1.7
|
||||||
|
##
|
||||||
|
{ 'struct': 'ImageInfoSpecificQCow2Wrapper',
|
||||||
|
'data': { 'data': 'ImageInfoSpecificQCow2' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @ImageInfoSpecificVmdkWrapper:
|
||||||
|
#
|
||||||
|
# Since: 6.1
|
||||||
|
##
|
||||||
|
{ 'struct': 'ImageInfoSpecificVmdkWrapper',
|
||||||
|
'data': { 'data': 'ImageInfoSpecificVmdk' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @ImageInfoSpecificLUKSWrapper:
|
||||||
|
#
|
||||||
|
# Since: 2.7
|
||||||
|
##
|
||||||
|
{ 'struct': 'ImageInfoSpecificLUKSWrapper',
|
||||||
|
'data': { 'data': 'QCryptoBlockInfoLUKS' } }
|
||||||
|
# If we need to add block driver specific parameters for
|
||||||
|
# LUKS in future, then we'll subclass QCryptoBlockInfoLUKS
|
||||||
|
# to define a ImageInfoSpecificLUKS
|
||||||
|
|
||||||
|
##
|
||||||
|
# @ImageInfoSpecificRbdWrapper:
|
||||||
|
#
|
||||||
|
# Since: 6.1
|
||||||
|
##
|
||||||
|
{ 'struct': 'ImageInfoSpecificRbdWrapper',
|
||||||
|
'data': { 'data': 'ImageInfoSpecificRbd' } }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @ImageInfoSpecific:
|
# @ImageInfoSpecific:
|
||||||
#
|
#
|
||||||
|
@ -147,14 +193,13 @@
|
||||||
# Since: 1.7
|
# Since: 1.7
|
||||||
##
|
##
|
||||||
{ 'union': 'ImageInfoSpecific',
|
{ 'union': 'ImageInfoSpecific',
|
||||||
|
'base': { 'type': 'ImageInfoSpecificKind' },
|
||||||
|
'discriminator': 'type',
|
||||||
'data': {
|
'data': {
|
||||||
'qcow2': 'ImageInfoSpecificQCow2',
|
'qcow2': 'ImageInfoSpecificQCow2Wrapper',
|
||||||
'vmdk': 'ImageInfoSpecificVmdk',
|
'vmdk': 'ImageInfoSpecificVmdkWrapper',
|
||||||
# If we need to add block driver specific parameters for
|
'luks': 'ImageInfoSpecificLUKSWrapper',
|
||||||
# LUKS in future, then we'll subclass QCryptoBlockInfoLUKS
|
'rbd': 'ImageInfoSpecificRbdWrapper'
|
||||||
# to define a ImageInfoSpecificLUKS
|
|
||||||
'luks': 'QCryptoBlockInfoLUKS',
|
|
||||||
'rbd': 'ImageInfoSpecificRbd'
|
|
||||||
} }
|
} }
|
||||||
|
|
||||||
##
|
##
|
||||||
|
|
190
qapi/char.json
190
qapi/char.json
|
@ -407,39 +407,185 @@
|
||||||
'base': 'ChardevCommon',
|
'base': 'ChardevCommon',
|
||||||
'if': 'CONFIG_SPICE_PROTOCOL' }
|
'if': 'CONFIG_SPICE_PROTOCOL' }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @ChardevBackendKind:
|
||||||
|
#
|
||||||
|
# @pipe: Since 1.5
|
||||||
|
# @udp: Since 1.5
|
||||||
|
# @mux: Since 1.5
|
||||||
|
# @msmouse: Since 1.5
|
||||||
|
# @wctablet: Since 2.9
|
||||||
|
# @braille: Since 1.5
|
||||||
|
# @testdev: Since 2.2
|
||||||
|
# @stdio: Since 1.5
|
||||||
|
# @console: Since 1.5
|
||||||
|
# @spicevmc: Since 1.5
|
||||||
|
# @spiceport: Since 1.5
|
||||||
|
# @qemu-vdagent: Since 6.1
|
||||||
|
# @vc: v1.5
|
||||||
|
# @ringbuf: Since 1.6
|
||||||
|
# @memory: Since 1.5
|
||||||
|
#
|
||||||
|
# Since: 1.4
|
||||||
|
##
|
||||||
|
{ 'enum': 'ChardevBackendKind',
|
||||||
|
'data': [ 'file',
|
||||||
|
'serial',
|
||||||
|
'parallel',
|
||||||
|
'pipe',
|
||||||
|
'socket',
|
||||||
|
'udp',
|
||||||
|
'pty',
|
||||||
|
'null',
|
||||||
|
'mux',
|
||||||
|
'msmouse',
|
||||||
|
'wctablet',
|
||||||
|
'braille',
|
||||||
|
'testdev',
|
||||||
|
'stdio',
|
||||||
|
'console',
|
||||||
|
{ 'name': 'spicevmc', 'if': 'CONFIG_SPICE' },
|
||||||
|
{ 'name': 'spiceport', 'if': 'CONFIG_SPICE' },
|
||||||
|
{ 'name': 'qemu-vdagent', 'if': 'CONFIG_SPICE_PROTOCOL' },
|
||||||
|
'vc',
|
||||||
|
'ringbuf',
|
||||||
|
# next one is just for compatibility
|
||||||
|
'memory' ] }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @ChardevFileWrapper:
|
||||||
|
#
|
||||||
|
# Since: 1.4
|
||||||
|
##
|
||||||
|
{ 'struct': 'ChardevFileWrapper',
|
||||||
|
'data': { 'data': 'ChardevFile' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @ChardevHostdevWrapper:
|
||||||
|
#
|
||||||
|
# Since: 1.4
|
||||||
|
##
|
||||||
|
{ 'struct': 'ChardevHostdevWrapper',
|
||||||
|
'data': { 'data': 'ChardevHostdev' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @ChardevSocketWrapper:
|
||||||
|
#
|
||||||
|
# Since: 1.4
|
||||||
|
##
|
||||||
|
{ 'struct': 'ChardevSocketWrapper',
|
||||||
|
'data': { 'data': 'ChardevSocket' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @ChardevUdpWrapper:
|
||||||
|
#
|
||||||
|
# Since: 1.5
|
||||||
|
##
|
||||||
|
{ 'struct': 'ChardevUdpWrapper',
|
||||||
|
'data': { 'data': 'ChardevUdp' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @ChardevCommonWrapper:
|
||||||
|
#
|
||||||
|
# Since: 2.6
|
||||||
|
##
|
||||||
|
{ 'struct': 'ChardevCommonWrapper',
|
||||||
|
'data': { 'data': 'ChardevCommon' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @ChardevMuxWrapper:
|
||||||
|
#
|
||||||
|
# Since: 1.5
|
||||||
|
##
|
||||||
|
{ 'struct': 'ChardevMuxWrapper',
|
||||||
|
'data': { 'data': 'ChardevMux' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @ChardevStdioWrapper:
|
||||||
|
#
|
||||||
|
# Since: 1.5
|
||||||
|
##
|
||||||
|
{ 'struct': 'ChardevStdioWrapper',
|
||||||
|
'data': { 'data': 'ChardevStdio' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @ChardevSpiceChannelWrapper:
|
||||||
|
#
|
||||||
|
# Since: 1.5
|
||||||
|
##
|
||||||
|
{ 'struct': 'ChardevSpiceChannelWrapper',
|
||||||
|
'data': { 'data': 'ChardevSpiceChannel' },
|
||||||
|
'if': 'CONFIG_SPICE' }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @ChardevSpicePortWrapper:
|
||||||
|
#
|
||||||
|
# Since: 1.5
|
||||||
|
##
|
||||||
|
{ 'struct': 'ChardevSpicePortWrapper',
|
||||||
|
'data': { 'data': 'ChardevSpicePort' },
|
||||||
|
'if': 'CONFIG_SPICE' }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @ChardevQemuVDAgentWrapper:
|
||||||
|
#
|
||||||
|
# Since: 6.1
|
||||||
|
##
|
||||||
|
{ 'struct': 'ChardevQemuVDAgentWrapper',
|
||||||
|
'data': { 'data': 'ChardevQemuVDAgent' },
|
||||||
|
'if': 'CONFIG_SPICE_PROTOCOL' }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @ChardevVCWrapper:
|
||||||
|
#
|
||||||
|
# Since: 1.5
|
||||||
|
##
|
||||||
|
{ 'struct': 'ChardevVCWrapper',
|
||||||
|
'data': { 'data': 'ChardevVC' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @ChardevRingbufWrapper:
|
||||||
|
#
|
||||||
|
# Since: 1.5
|
||||||
|
##
|
||||||
|
{ 'struct': 'ChardevRingbufWrapper',
|
||||||
|
'data': { 'data': 'ChardevRingbuf' } }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @ChardevBackend:
|
# @ChardevBackend:
|
||||||
#
|
#
|
||||||
# Configuration info for the new chardev backend.
|
# Configuration info for the new chardev backend.
|
||||||
#
|
#
|
||||||
# Since: 1.4 (testdev since 2.2, wctablet since 2.9, vdagent since 6.1)
|
# Since: 1.4
|
||||||
##
|
##
|
||||||
{ 'union': 'ChardevBackend',
|
{ 'union': 'ChardevBackend',
|
||||||
'data': { 'file': 'ChardevFile',
|
'base': { 'type': 'ChardevBackendKind' },
|
||||||
'serial': 'ChardevHostdev',
|
'discriminator': 'type',
|
||||||
'parallel': 'ChardevHostdev',
|
'data': { 'file': 'ChardevFileWrapper',
|
||||||
'pipe': 'ChardevHostdev',
|
'serial': 'ChardevHostdevWrapper',
|
||||||
'socket': 'ChardevSocket',
|
'parallel': 'ChardevHostdevWrapper',
|
||||||
'udp': 'ChardevUdp',
|
'pipe': 'ChardevHostdevWrapper',
|
||||||
'pty': 'ChardevCommon',
|
'socket': 'ChardevSocketWrapper',
|
||||||
'null': 'ChardevCommon',
|
'udp': 'ChardevUdpWrapper',
|
||||||
'mux': 'ChardevMux',
|
'pty': 'ChardevCommonWrapper',
|
||||||
'msmouse': 'ChardevCommon',
|
'null': 'ChardevCommonWrapper',
|
||||||
'wctablet': 'ChardevCommon',
|
'mux': 'ChardevMuxWrapper',
|
||||||
'braille': 'ChardevCommon',
|
'msmouse': 'ChardevCommonWrapper',
|
||||||
'testdev': 'ChardevCommon',
|
'wctablet': 'ChardevCommonWrapper',
|
||||||
'stdio': 'ChardevStdio',
|
'braille': 'ChardevCommonWrapper',
|
||||||
'console': 'ChardevCommon',
|
'testdev': 'ChardevCommonWrapper',
|
||||||
'spicevmc': { 'type': 'ChardevSpiceChannel',
|
'stdio': 'ChardevStdioWrapper',
|
||||||
|
'console': 'ChardevCommonWrapper',
|
||||||
|
'spicevmc': { 'type': 'ChardevSpiceChannelWrapper',
|
||||||
'if': 'CONFIG_SPICE' },
|
'if': 'CONFIG_SPICE' },
|
||||||
'spiceport': { 'type': 'ChardevSpicePort',
|
'spiceport': { 'type': 'ChardevSpicePortWrapper',
|
||||||
'if': 'CONFIG_SPICE' },
|
'if': 'CONFIG_SPICE' },
|
||||||
'qemu-vdagent': { 'type': 'ChardevQemuVDAgent',
|
'qemu-vdagent': { 'type': 'ChardevQemuVDAgentWrapper',
|
||||||
'if': 'CONFIG_SPICE_PROTOCOL' },
|
'if': 'CONFIG_SPICE_PROTOCOL' },
|
||||||
'vc': 'ChardevVC',
|
'vc': 'ChardevVCWrapper',
|
||||||
'ringbuf': 'ChardevRingbuf',
|
'ringbuf': 'ChardevRingbufWrapper',
|
||||||
# next one is just for compatibility
|
# next one is just for compatibility
|
||||||
'memory': 'ChardevRingbuf' } }
|
'memory': 'ChardevRingbufWrapper' } }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @ChardevReturn:
|
# @ChardevReturn:
|
||||||
|
|
|
@ -1194,6 +1194,38 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
##
|
||||||
|
# @MemoryDeviceInfoKind:
|
||||||
|
#
|
||||||
|
# Since: 2.1
|
||||||
|
##
|
||||||
|
{ 'enum': 'MemoryDeviceInfoKind',
|
||||||
|
'data': [ 'dimm', 'nvdimm', 'virtio-pmem', 'virtio-mem' ] }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @PCDIMMDeviceInfoWrapper:
|
||||||
|
#
|
||||||
|
# Since: 2.1
|
||||||
|
##
|
||||||
|
{ 'struct': 'PCDIMMDeviceInfoWrapper',
|
||||||
|
'data': { 'data': 'PCDIMMDeviceInfo' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @VirtioPMEMDeviceInfoWrapper:
|
||||||
|
#
|
||||||
|
# Since: 2.1
|
||||||
|
##
|
||||||
|
{ 'struct': 'VirtioPMEMDeviceInfoWrapper',
|
||||||
|
'data': { 'data': 'VirtioPMEMDeviceInfo' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @VirtioMEMDeviceInfoWrapper:
|
||||||
|
#
|
||||||
|
# Since: 2.1
|
||||||
|
##
|
||||||
|
{ 'struct': 'VirtioMEMDeviceInfoWrapper',
|
||||||
|
'data': { 'data': 'VirtioMEMDeviceInfo' } }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @MemoryDeviceInfo:
|
# @MemoryDeviceInfo:
|
||||||
#
|
#
|
||||||
|
@ -1205,10 +1237,12 @@
|
||||||
# Since: 2.1
|
# Since: 2.1
|
||||||
##
|
##
|
||||||
{ 'union': 'MemoryDeviceInfo',
|
{ 'union': 'MemoryDeviceInfo',
|
||||||
'data': { 'dimm': 'PCDIMMDeviceInfo',
|
'base': { 'type': 'MemoryDeviceInfoKind' },
|
||||||
'nvdimm': 'PCDIMMDeviceInfo',
|
'discriminator': 'type',
|
||||||
'virtio-pmem': 'VirtioPMEMDeviceInfo',
|
'data': { 'dimm': 'PCDIMMDeviceInfoWrapper',
|
||||||
'virtio-mem': 'VirtioMEMDeviceInfo'
|
'nvdimm': 'PCDIMMDeviceInfoWrapper',
|
||||||
|
'virtio-pmem': 'VirtioPMEMDeviceInfoWrapper',
|
||||||
|
'virtio-mem': 'VirtioMEMDeviceInfoWrapper'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -110,6 +110,38 @@
|
||||||
'cid': 'str',
|
'cid': 'str',
|
||||||
'port': 'str' } }
|
'port': 'str' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @InetSocketAddressWrapper:
|
||||||
|
#
|
||||||
|
# Since: 1.3
|
||||||
|
##
|
||||||
|
{ 'struct': 'InetSocketAddressWrapper',
|
||||||
|
'data': { 'data': 'InetSocketAddress' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @UnixSocketAddressWrapper:
|
||||||
|
#
|
||||||
|
# Since: 1.3
|
||||||
|
##
|
||||||
|
{ 'struct': 'UnixSocketAddressWrapper',
|
||||||
|
'data': { 'data': 'UnixSocketAddress' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @VsockSocketAddressWrapper:
|
||||||
|
#
|
||||||
|
# Since: 2.8
|
||||||
|
##
|
||||||
|
{ 'struct': 'VsockSocketAddressWrapper',
|
||||||
|
'data': { 'data': 'VsockSocketAddress' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @StringWrapper:
|
||||||
|
#
|
||||||
|
# Since: 1.3
|
||||||
|
##
|
||||||
|
{ 'struct': 'StringWrapper',
|
||||||
|
'data': { 'data': 'String' } }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @SocketAddressLegacy:
|
# @SocketAddressLegacy:
|
||||||
#
|
#
|
||||||
|
@ -117,18 +149,18 @@
|
||||||
#
|
#
|
||||||
# Note: This type is deprecated in favor of SocketAddress. The
|
# Note: This type is deprecated in favor of SocketAddress. The
|
||||||
# difference between SocketAddressLegacy and SocketAddress is that the
|
# difference between SocketAddressLegacy and SocketAddress is that the
|
||||||
# latter is a flat union rather than a simple union. Flat is nicer
|
# latter is has fewer {} on the wire.
|
||||||
# because it avoids nesting on the wire, i.e. that form has fewer {}.
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Since: 1.3
|
# Since: 1.3
|
||||||
##
|
##
|
||||||
{ 'union': 'SocketAddressLegacy',
|
{ 'union': 'SocketAddressLegacy',
|
||||||
|
'base': { 'type': 'SocketAddressType' },
|
||||||
|
'discriminator': 'type',
|
||||||
'data': {
|
'data': {
|
||||||
'inet': 'InetSocketAddress',
|
'inet': 'InetSocketAddressWrapper',
|
||||||
'unix': 'UnixSocketAddress',
|
'unix': 'UnixSocketAddressWrapper',
|
||||||
'vsock': 'VsockSocketAddress',
|
'vsock': 'VsockSocketAddressWrapper',
|
||||||
'fd': 'String' } }
|
'fd': 'StringWrapper' } }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @SocketAddressType:
|
# @SocketAddressType:
|
||||||
|
|
|
@ -99,6 +99,24 @@
|
||||||
{ 'struct': 'TPMEmulatorOptions', 'data': { 'chardev' : 'str' },
|
{ 'struct': 'TPMEmulatorOptions', 'data': { 'chardev' : 'str' },
|
||||||
'if': 'CONFIG_TPM' }
|
'if': 'CONFIG_TPM' }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @TPMPassthroughOptionsWrapper:
|
||||||
|
#
|
||||||
|
# Since: 1.5
|
||||||
|
##
|
||||||
|
{ 'struct': 'TPMPassthroughOptionsWrapper',
|
||||||
|
'data': { 'data': 'TPMPassthroughOptions' },
|
||||||
|
'if': 'CONFIG_TPM' }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @TPMEmulatorOptionsWrapper:
|
||||||
|
#
|
||||||
|
# Since: 2.11
|
||||||
|
##
|
||||||
|
{ 'struct': 'TPMEmulatorOptionsWrapper',
|
||||||
|
'data': { 'data': 'TPMEmulatorOptions' },
|
||||||
|
'if': 'CONFIG_TPM' }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @TpmTypeOptions:
|
# @TpmTypeOptions:
|
||||||
#
|
#
|
||||||
|
@ -110,8 +128,10 @@
|
||||||
# Since: 1.5
|
# Since: 1.5
|
||||||
##
|
##
|
||||||
{ 'union': 'TpmTypeOptions',
|
{ 'union': 'TpmTypeOptions',
|
||||||
'data': { 'passthrough' : 'TPMPassthroughOptions',
|
'base': { 'type': 'TpmType' },
|
||||||
'emulator': 'TPMEmulatorOptions' },
|
'discriminator': 'type',
|
||||||
|
'data': { 'passthrough' : 'TPMPassthroughOptionsWrapper',
|
||||||
|
'emulator': 'TPMEmulatorOptionsWrapper' },
|
||||||
'if': 'CONFIG_TPM' }
|
'if': 'CONFIG_TPM' }
|
||||||
|
|
||||||
##
|
##
|
||||||
|
|
|
@ -38,41 +38,128 @@
|
||||||
{ 'enum': 'ActionCompletionMode',
|
{ 'enum': 'ActionCompletionMode',
|
||||||
'data': [ 'individual', 'grouped' ] }
|
'data': [ 'individual', 'grouped' ] }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @TransactionActionKind:
|
||||||
|
#
|
||||||
|
# @abort: Since 1.6
|
||||||
|
# @block-dirty-bitmap-add: Since 2.5
|
||||||
|
# @block-dirty-bitmap-remove: Since 4.2
|
||||||
|
# @block-dirty-bitmap-clear: Since 2.5
|
||||||
|
# @block-dirty-bitmap-enable: Since 4.0
|
||||||
|
# @block-dirty-bitmap-disable: Since 4.0
|
||||||
|
# @block-dirty-bitmap-merge: Since 4.0
|
||||||
|
# @blockdev-backup: Since 2.3
|
||||||
|
# @blockdev-snapshot: Since 2.5
|
||||||
|
# @blockdev-snapshot-internal-sync: Since 1.7
|
||||||
|
# @blockdev-snapshot-sync: since 1.1
|
||||||
|
# @drive-backup: Since 1.6
|
||||||
|
#
|
||||||
|
# Since: 1.1
|
||||||
|
##
|
||||||
|
{ 'enum': 'TransactionActionKind',
|
||||||
|
'data': [ 'abort', 'block-dirty-bitmap-add', 'block-dirty-bitmap-remove',
|
||||||
|
'block-dirty-bitmap-clear', 'block-dirty-bitmap-enable',
|
||||||
|
'block-dirty-bitmap-disable', 'block-dirty-bitmap-merge',
|
||||||
|
'blockdev-backup', 'blockdev-snapshot',
|
||||||
|
'blockdev-snapshot-internal-sync', 'blockdev-snapshot-sync',
|
||||||
|
'drive-backup' ] }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @AbortWrapper:
|
||||||
|
#
|
||||||
|
# Since: 1.6
|
||||||
|
##
|
||||||
|
{ 'struct': 'AbortWrapper',
|
||||||
|
'data': { 'data': 'Abort' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @BlockDirtyBitmapAddWrapper:
|
||||||
|
#
|
||||||
|
# Since: 2.5
|
||||||
|
##
|
||||||
|
{ 'struct': 'BlockDirtyBitmapAddWrapper',
|
||||||
|
'data': { 'data': 'BlockDirtyBitmapAdd' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @BlockDirtyBitmapWrapper:
|
||||||
|
#
|
||||||
|
# Since: 2.5
|
||||||
|
##
|
||||||
|
{ 'struct': 'BlockDirtyBitmapWrapper',
|
||||||
|
'data': { 'data': 'BlockDirtyBitmap' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @BlockDirtyBitmapMergeWrapper:
|
||||||
|
#
|
||||||
|
# Since: 4.0
|
||||||
|
##
|
||||||
|
{ 'struct': 'BlockDirtyBitmapMergeWrapper',
|
||||||
|
'data': { 'data': 'BlockDirtyBitmapMerge' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @BlockdevBackupWrapper:
|
||||||
|
#
|
||||||
|
# Since: 2.3
|
||||||
|
##
|
||||||
|
{ 'struct': 'BlockdevBackupWrapper',
|
||||||
|
'data': { 'data': 'BlockdevBackup' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @BlockdevSnapshotWrapper:
|
||||||
|
#
|
||||||
|
# Since: 2.5
|
||||||
|
##
|
||||||
|
{ 'struct': 'BlockdevSnapshotWrapper',
|
||||||
|
'data': { 'data': 'BlockdevSnapshot' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @BlockdevSnapshotInternalWrapper:
|
||||||
|
#
|
||||||
|
# Since: 1.7
|
||||||
|
##
|
||||||
|
{ 'struct': 'BlockdevSnapshotInternalWrapper',
|
||||||
|
'data': { 'data': 'BlockdevSnapshotInternal' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @BlockdevSnapshotSyncWrapper:
|
||||||
|
#
|
||||||
|
# Since: 1.1
|
||||||
|
##
|
||||||
|
{ 'struct': 'BlockdevSnapshotSyncWrapper',
|
||||||
|
'data': { 'data': 'BlockdevSnapshotSync' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @DriveBackupWrapper:
|
||||||
|
#
|
||||||
|
# Since: 1.6
|
||||||
|
##
|
||||||
|
{ 'struct': 'DriveBackupWrapper',
|
||||||
|
'data': { 'data': 'DriveBackup' } }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @TransactionAction:
|
# @TransactionAction:
|
||||||
#
|
#
|
||||||
# A discriminated record of operations that can be performed with
|
# A discriminated record of operations that can be performed with
|
||||||
# @transaction. Action @type can be:
|
# @transaction.
|
||||||
#
|
|
||||||
# - @abort: since 1.6
|
|
||||||
# - @block-dirty-bitmap-add: since 2.5
|
|
||||||
# - @block-dirty-bitmap-remove: since 4.2
|
|
||||||
# - @block-dirty-bitmap-clear: since 2.5
|
|
||||||
# - @block-dirty-bitmap-enable: since 4.0
|
|
||||||
# - @block-dirty-bitmap-disable: since 4.0
|
|
||||||
# - @block-dirty-bitmap-merge: since 4.0
|
|
||||||
# - @blockdev-backup: since 2.3
|
|
||||||
# - @blockdev-snapshot: since 2.5
|
|
||||||
# - @blockdev-snapshot-internal-sync: since 1.7
|
|
||||||
# - @blockdev-snapshot-sync: since 1.1
|
|
||||||
# - @drive-backup: since 1.6
|
|
||||||
#
|
#
|
||||||
# Since: 1.1
|
# Since: 1.1
|
||||||
##
|
##
|
||||||
{ 'union': 'TransactionAction',
|
{ 'union': 'TransactionAction',
|
||||||
|
'base': { 'type': 'TransactionActionKind' },
|
||||||
|
'discriminator': 'type',
|
||||||
'data': {
|
'data': {
|
||||||
'abort': 'Abort',
|
'abort': 'AbortWrapper',
|
||||||
'block-dirty-bitmap-add': 'BlockDirtyBitmapAdd',
|
'block-dirty-bitmap-add': 'BlockDirtyBitmapAddWrapper',
|
||||||
'block-dirty-bitmap-remove': 'BlockDirtyBitmap',
|
'block-dirty-bitmap-remove': 'BlockDirtyBitmapWrapper',
|
||||||
'block-dirty-bitmap-clear': 'BlockDirtyBitmap',
|
'block-dirty-bitmap-clear': 'BlockDirtyBitmapWrapper',
|
||||||
'block-dirty-bitmap-enable': 'BlockDirtyBitmap',
|
'block-dirty-bitmap-enable': 'BlockDirtyBitmapWrapper',
|
||||||
'block-dirty-bitmap-disable': 'BlockDirtyBitmap',
|
'block-dirty-bitmap-disable': 'BlockDirtyBitmapWrapper',
|
||||||
'block-dirty-bitmap-merge': 'BlockDirtyBitmapMerge',
|
'block-dirty-bitmap-merge': 'BlockDirtyBitmapMergeWrapper',
|
||||||
'blockdev-backup': 'BlockdevBackup',
|
'blockdev-backup': 'BlockdevBackupWrapper',
|
||||||
'blockdev-snapshot': 'BlockdevSnapshot',
|
'blockdev-snapshot': 'BlockdevSnapshotWrapper',
|
||||||
'blockdev-snapshot-internal-sync': 'BlockdevSnapshotInternal',
|
'blockdev-snapshot-internal-sync': 'BlockdevSnapshotInternalWrapper',
|
||||||
'blockdev-snapshot-sync': 'BlockdevSnapshotSync',
|
'blockdev-snapshot-sync': 'BlockdevSnapshotSyncWrapper',
|
||||||
'drive-backup': 'DriveBackup'
|
'drive-backup': 'DriveBackupWrapper'
|
||||||
} }
|
} }
|
||||||
|
|
||||||
##
|
##
|
||||||
|
|
72
qapi/ui.json
72
qapi/ui.json
|
@ -824,6 +824,30 @@
|
||||||
'ac_home', 'ac_back', 'ac_forward', 'ac_refresh', 'ac_bookmarks',
|
'ac_home', 'ac_back', 'ac_forward', 'ac_refresh', 'ac_bookmarks',
|
||||||
'lang1', 'lang2' ] }
|
'lang1', 'lang2' ] }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @KeyValueKind:
|
||||||
|
#
|
||||||
|
# Since: 1.3
|
||||||
|
##
|
||||||
|
{ 'enum': 'KeyValueKind',
|
||||||
|
'data': [ 'number', 'qcode' ] }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @IntWrapper:
|
||||||
|
#
|
||||||
|
# Since: 1.3
|
||||||
|
##
|
||||||
|
{ 'struct': 'IntWrapper',
|
||||||
|
'data': { 'data': 'int' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @QKeyCodeWrapper:
|
||||||
|
#
|
||||||
|
# Since: 1.3
|
||||||
|
##
|
||||||
|
{ 'struct': 'QKeyCodeWrapper',
|
||||||
|
'data': { 'data': 'QKeyCode' } }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @KeyValue:
|
# @KeyValue:
|
||||||
#
|
#
|
||||||
|
@ -832,9 +856,11 @@
|
||||||
# Since: 1.3
|
# Since: 1.3
|
||||||
##
|
##
|
||||||
{ 'union': 'KeyValue',
|
{ 'union': 'KeyValue',
|
||||||
|
'base': { 'type': 'KeyValueKind' },
|
||||||
|
'discriminator': 'type',
|
||||||
'data': {
|
'data': {
|
||||||
'number': 'int',
|
'number': 'IntWrapper',
|
||||||
'qcode': 'QKeyCode' } }
|
'qcode': 'QKeyCodeWrapper' } }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @send-key:
|
# @send-key:
|
||||||
|
@ -934,6 +960,38 @@
|
||||||
'data' : { 'axis' : 'InputAxis',
|
'data' : { 'axis' : 'InputAxis',
|
||||||
'value' : 'int' } }
|
'value' : 'int' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @InputEventKind:
|
||||||
|
#
|
||||||
|
# Since: 2.0
|
||||||
|
##
|
||||||
|
{ 'enum': 'InputEventKind',
|
||||||
|
'data': [ 'key', 'btn', 'rel', 'abs' ] }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @InputKeyEventWrapper:
|
||||||
|
#
|
||||||
|
# Since: 2.0
|
||||||
|
##
|
||||||
|
{ 'struct': 'InputKeyEventWrapper',
|
||||||
|
'data': { 'data': 'InputKeyEvent' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @InputBtnEventWrapper:
|
||||||
|
#
|
||||||
|
# Since: 2.0
|
||||||
|
##
|
||||||
|
{ 'struct': 'InputBtnEventWrapper',
|
||||||
|
'data': { 'data': 'InputBtnEvent' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @InputMoveEventWrapper:
|
||||||
|
#
|
||||||
|
# Since: 2.0
|
||||||
|
##
|
||||||
|
{ 'struct': 'InputMoveEventWrapper',
|
||||||
|
'data': { 'data': 'InputMoveEvent' } }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @InputEvent:
|
# @InputEvent:
|
||||||
#
|
#
|
||||||
|
@ -949,10 +1007,12 @@
|
||||||
# Since: 2.0
|
# Since: 2.0
|
||||||
##
|
##
|
||||||
{ 'union' : 'InputEvent',
|
{ 'union' : 'InputEvent',
|
||||||
'data' : { 'key' : 'InputKeyEvent',
|
'base': { 'type': 'InputEventKind' },
|
||||||
'btn' : 'InputBtnEvent',
|
'discriminator': 'type',
|
||||||
'rel' : 'InputMoveEvent',
|
'data' : { 'key' : 'InputKeyEventWrapper',
|
||||||
'abs' : 'InputMoveEvent' } }
|
'btn' : 'InputBtnEventWrapper',
|
||||||
|
'rel' : 'InputMoveEventWrapper',
|
||||||
|
'abs' : 'InputMoveEventWrapper' } }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @input-send-event:
|
# @input-send-event:
|
||||||
|
|
|
@ -171,7 +171,7 @@ def check_defn_name_str(name: str, info: QAPISourceInfo, meta: str) -> None:
|
||||||
- 'event' names adhere to `check_name_upper()`.
|
- 'event' names adhere to `check_name_upper()`.
|
||||||
- 'command' names adhere to `check_name_lower()`.
|
- 'command' names adhere to `check_name_lower()`.
|
||||||
- Else, meta is a type, and must pass `check_name_camel()`.
|
- Else, meta is a type, and must pass `check_name_camel()`.
|
||||||
These names must not end with ``Kind`` nor ``List``.
|
These names must not end with ``List``.
|
||||||
|
|
||||||
:param name: Name to check.
|
:param name: Name to check.
|
||||||
:param info: QAPI schema source file information.
|
:param info: QAPI schema source file information.
|
||||||
|
@ -187,9 +187,9 @@ def check_defn_name_str(name: str, info: QAPISourceInfo, meta: str) -> None:
|
||||||
permit_underscore=name in info.pragma.command_name_exceptions)
|
permit_underscore=name in info.pragma.command_name_exceptions)
|
||||||
else:
|
else:
|
||||||
check_name_camel(name, info, meta)
|
check_name_camel(name, info, meta)
|
||||||
if name.endswith('Kind') or name.endswith('List'):
|
if name.endswith('List'):
|
||||||
raise QAPISemError(
|
raise QAPISemError(
|
||||||
info, "%s name should not end in '%s'" % (meta, name[-4:]))
|
info, "%s name should not end in 'List'" % meta)
|
||||||
|
|
||||||
|
|
||||||
def check_keys(value: _JSONObject,
|
def check_keys(value: _JSONObject,
|
||||||
|
@ -513,27 +513,18 @@ def check_union(expr: _JSONObject, info: QAPISourceInfo) -> None:
|
||||||
:return: None, ``expr`` is normalized in-place as needed.
|
:return: None, ``expr`` is normalized in-place as needed.
|
||||||
"""
|
"""
|
||||||
name = cast(str, expr['union']) # Checked in check_exprs
|
name = cast(str, expr['union']) # Checked in check_exprs
|
||||||
base = expr.get('base')
|
base = expr['base']
|
||||||
discriminator = expr.get('discriminator')
|
discriminator = expr['discriminator']
|
||||||
members = expr['data']
|
members = expr['data']
|
||||||
|
|
||||||
if discriminator is None: # simple union
|
check_type(base, info, "'base'", allow_dict=name)
|
||||||
if base is not None:
|
check_name_is_str(discriminator, info, "'discriminator'")
|
||||||
raise QAPISemError(info, "'base' requires 'discriminator'")
|
|
||||||
else: # flat union
|
|
||||||
check_type(base, info, "'base'", allow_dict=name)
|
|
||||||
if not base:
|
|
||||||
raise QAPISemError(info, "'discriminator' requires 'base'")
|
|
||||||
check_name_is_str(discriminator, info, "'discriminator'")
|
|
||||||
|
|
||||||
if not isinstance(members, dict):
|
if not isinstance(members, dict):
|
||||||
raise QAPISemError(info, "'data' must be an object")
|
raise QAPISemError(info, "'data' must be an object")
|
||||||
|
|
||||||
for (key, value) in members.items():
|
for (key, value) in members.items():
|
||||||
source = "'data' member '%s'" % key
|
source = "'data' member '%s'" % key
|
||||||
if discriminator is None:
|
|
||||||
check_name_lower(key, info, source)
|
|
||||||
# else: name is in discriminator enum, which gets checked
|
|
||||||
check_keys(value, info, source, ['type'], ['if'])
|
check_keys(value, info, source, ['type'], ['if'])
|
||||||
check_if(value, info, source)
|
check_if(value, info, source)
|
||||||
check_type(value['type'], info, source, allow_array=not base)
|
check_type(value['type'], info, source, allow_array=not base)
|
||||||
|
@ -664,8 +655,8 @@ def check_exprs(exprs: List[_JSONObject]) -> List[_JSONObject]:
|
||||||
check_enum(expr, info)
|
check_enum(expr, info)
|
||||||
elif meta == 'union':
|
elif meta == 'union':
|
||||||
check_keys(expr, info, meta,
|
check_keys(expr, info, meta,
|
||||||
['union', 'data'],
|
['union', 'base', 'discriminator', 'data'],
|
||||||
['base', 'discriminator', 'if', 'features'])
|
['if', 'features'])
|
||||||
normalize_members(expr.get('base'))
|
normalize_members(expr.get('base'))
|
||||||
normalize_members(expr['data'])
|
normalize_members(expr['data'])
|
||||||
check_union(expr, info)
|
check_union(expr, info)
|
||||||
|
|
|
@ -321,8 +321,8 @@ class QAPISchemaEnumType(QAPISchemaType):
|
||||||
m.connect_doc(doc)
|
m.connect_doc(doc)
|
||||||
|
|
||||||
def is_implicit(self):
|
def is_implicit(self):
|
||||||
# See QAPISchema._make_implicit_enum_type() and ._def_predefineds()
|
# See QAPISchema._def_predefineds()
|
||||||
return self.name.endswith('Kind') or self.name == 'QType'
|
return self.name == 'QType'
|
||||||
|
|
||||||
def c_type(self):
|
def c_type(self):
|
||||||
return c_name(self.name)
|
return c_name(self.name)
|
||||||
|
@ -393,8 +393,7 @@ class QAPISchemaObjectType(QAPISchemaType):
|
||||||
def __init__(self, name, info, doc, ifcond, features,
|
def __init__(self, name, info, doc, ifcond, features,
|
||||||
base, local_members, variants):
|
base, local_members, variants):
|
||||||
# struct has local_members, optional base, and no variants
|
# struct has local_members, optional base, and no variants
|
||||||
# flat union has base, variants, and no local_members
|
# union has base, variants, and no local_members
|
||||||
# simple union has local_members, variants, and no base
|
|
||||||
super().__init__(name, info, doc, ifcond, features)
|
super().__init__(name, info, doc, ifcond, features)
|
||||||
self.meta = 'union' if variants else 'struct'
|
self.meta = 'union' if variants else 'struct'
|
||||||
assert base is None or isinstance(base, str)
|
assert base is None or isinstance(base, str)
|
||||||
|
@ -465,15 +464,6 @@ class QAPISchemaObjectType(QAPISchemaType):
|
||||||
for m in self.local_members:
|
for m in self.local_members:
|
||||||
m.connect_doc(doc)
|
m.connect_doc(doc)
|
||||||
|
|
||||||
@property
|
|
||||||
def ifcond(self):
|
|
||||||
assert self._checked
|
|
||||||
if isinstance(self._ifcond, QAPISchemaType):
|
|
||||||
# Simple union wrapper type inherits from wrapped type;
|
|
||||||
# see _make_implicit_object_type()
|
|
||||||
return self._ifcond.ifcond
|
|
||||||
return self._ifcond
|
|
||||||
|
|
||||||
def is_implicit(self):
|
def is_implicit(self):
|
||||||
# See QAPISchema._make_implicit_object_type(), as well as
|
# See QAPISchema._make_implicit_object_type(), as well as
|
||||||
# _def_predefineds()
|
# _def_predefineds()
|
||||||
|
@ -576,10 +566,9 @@ class QAPISchemaAlternateType(QAPISchemaType):
|
||||||
|
|
||||||
class QAPISchemaVariants:
|
class QAPISchemaVariants:
|
||||||
def __init__(self, tag_name, info, tag_member, variants):
|
def __init__(self, tag_name, info, tag_member, variants):
|
||||||
# Flat unions pass tag_name but not tag_member.
|
# Unions pass tag_name but not tag_member.
|
||||||
# Simple unions and alternates pass tag_member but not tag_name.
|
# Alternates pass tag_member but not tag_name.
|
||||||
# After check(), tag_member is always set, and tag_name remains
|
# After check(), tag_member is always set.
|
||||||
# a reliable witness of being used by a flat union.
|
|
||||||
assert bool(tag_member) != bool(tag_name)
|
assert bool(tag_member) != bool(tag_name)
|
||||||
assert (isinstance(tag_name, str) or
|
assert (isinstance(tag_name, str) or
|
||||||
isinstance(tag_member, QAPISchemaObjectTypeMember))
|
isinstance(tag_member, QAPISchemaObjectTypeMember))
|
||||||
|
@ -595,7 +584,7 @@ class QAPISchemaVariants:
|
||||||
v.set_defined_in(name)
|
v.set_defined_in(name)
|
||||||
|
|
||||||
def check(self, schema, seen):
|
def check(self, schema, seen):
|
||||||
if not self.tag_member: # flat union
|
if self._tag_name: # union
|
||||||
self.tag_member = seen.get(c_name(self._tag_name))
|
self.tag_member = seen.get(c_name(self._tag_name))
|
||||||
base = "'base'"
|
base = "'base'"
|
||||||
# Pointing to the base type when not implicit would be
|
# Pointing to the base type when not implicit would be
|
||||||
|
@ -625,11 +614,11 @@ class QAPISchemaVariants:
|
||||||
self.info,
|
self.info,
|
||||||
"discriminator member '%s' of %s must not be conditional"
|
"discriminator member '%s' of %s must not be conditional"
|
||||||
% (self._tag_name, base))
|
% (self._tag_name, base))
|
||||||
else: # simple union
|
else: # alternate
|
||||||
assert isinstance(self.tag_member.type, QAPISchemaEnumType)
|
assert isinstance(self.tag_member.type, QAPISchemaEnumType)
|
||||||
assert not self.tag_member.optional
|
assert not self.tag_member.optional
|
||||||
assert not self.tag_member.ifcond.is_present()
|
assert not self.tag_member.ifcond.is_present()
|
||||||
if self._tag_name: # flat union
|
if self._tag_name: # union
|
||||||
# branches that are not explicitly covered get an empty type
|
# branches that are not explicitly covered get an empty type
|
||||||
cases = {v.name for v in self.variants}
|
cases = {v.name for v in self.variants}
|
||||||
for m in self.tag_member.type.members:
|
for m in self.tag_member.type.members:
|
||||||
|
@ -707,18 +696,10 @@ class QAPISchemaMember:
|
||||||
assert role == 'member'
|
assert role == 'member'
|
||||||
role = 'parameter'
|
role = 'parameter'
|
||||||
elif defined_in.endswith('-base'):
|
elif defined_in.endswith('-base'):
|
||||||
# Implicit type created for a flat union's dict 'base'
|
# Implicit type created for a union's dict 'base'
|
||||||
role = 'base ' + role
|
role = 'base ' + role
|
||||||
else:
|
else:
|
||||||
# Implicit type created for a simple union's branch
|
|
||||||
assert defined_in.endswith('-wrapper')
|
|
||||||
# Unreachable and not implemented
|
|
||||||
assert False
|
assert False
|
||||||
elif defined_in.endswith('Kind'):
|
|
||||||
# See QAPISchema._make_implicit_enum_type()
|
|
||||||
# Implicit enum created for simple union's branches
|
|
||||||
assert role == 'value'
|
|
||||||
role = 'branch'
|
|
||||||
elif defined_in != info.defn_name:
|
elif defined_in != info.defn_name:
|
||||||
return "%s '%s' of type '%s'" % (role, self.name, defined_in)
|
return "%s '%s' of type '%s'" % (role, self.name, defined_in)
|
||||||
return "%s '%s'" % (role, self.name)
|
return "%s '%s'" % (role, self.name)
|
||||||
|
@ -1004,15 +985,6 @@ class QAPISchema:
|
||||||
QAPISchemaIfCond(v.get('if')))
|
QAPISchemaIfCond(v.get('if')))
|
||||||
for v in values]
|
for v in values]
|
||||||
|
|
||||||
def _make_implicit_enum_type(self, name, info, ifcond, values):
|
|
||||||
# See also QAPISchemaObjectTypeMember.describe()
|
|
||||||
name = name + 'Kind' # reserved by check_defn_name_str()
|
|
||||||
self._def_entity(QAPISchemaEnumType(
|
|
||||||
name, info, None, ifcond, None,
|
|
||||||
self._make_enum_members(values, info),
|
|
||||||
None))
|
|
||||||
return name
|
|
||||||
|
|
||||||
def _make_array_type(self, element_type, info):
|
def _make_array_type(self, element_type, info):
|
||||||
name = element_type + 'List' # reserved by check_defn_name_str()
|
name = element_type + 'List' # reserved by check_defn_name_str()
|
||||||
if not self.lookup_type(name):
|
if not self.lookup_type(name):
|
||||||
|
@ -1026,17 +998,9 @@ class QAPISchema:
|
||||||
name = 'q_obj_%s-%s' % (name, role)
|
name = 'q_obj_%s-%s' % (name, role)
|
||||||
typ = self.lookup_entity(name, QAPISchemaObjectType)
|
typ = self.lookup_entity(name, QAPISchemaObjectType)
|
||||||
if typ:
|
if typ:
|
||||||
# The implicit object type has multiple users. This is
|
# The implicit object type has multiple users. This can
|
||||||
# either a duplicate definition (which will be flagged
|
# only be a duplicate definition, which will be flagged
|
||||||
# later), or an implicit wrapper type used for multiple
|
# later.
|
||||||
# simple unions. In the latter case, ifcond should be the
|
|
||||||
# disjunction of its user's ifconds. Not implemented.
|
|
||||||
# Instead, we always pass the wrapped type's ifcond, which
|
|
||||||
# is trivially the same for all users. It's also
|
|
||||||
# necessary for the wrapper to compile. But it's not
|
|
||||||
# tight: the disjunction need not imply it. We may end up
|
|
||||||
# compiling useless wrapper types.
|
|
||||||
# TODO kill simple unions or implement the disjunction
|
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
self._def_entity(QAPISchemaObjectType(
|
self._def_entity(QAPISchemaObjectType(
|
||||||
|
@ -1084,49 +1048,28 @@ class QAPISchema:
|
||||||
def _make_variant(self, case, typ, ifcond, info):
|
def _make_variant(self, case, typ, ifcond, info):
|
||||||
return QAPISchemaVariant(case, info, typ, ifcond)
|
return QAPISchemaVariant(case, info, typ, ifcond)
|
||||||
|
|
||||||
def _make_simple_variant(self, case, typ, ifcond, info):
|
|
||||||
if isinstance(typ, list):
|
|
||||||
assert len(typ) == 1
|
|
||||||
typ = self._make_array_type(typ[0], info)
|
|
||||||
typ = self._make_implicit_object_type(
|
|
||||||
typ, info, self.lookup_type(typ),
|
|
||||||
'wrapper', [self._make_member('data', typ, None, None, info)])
|
|
||||||
return QAPISchemaVariant(case, info, typ, ifcond)
|
|
||||||
|
|
||||||
def _def_union_type(self, expr, info, doc):
|
def _def_union_type(self, expr, info, doc):
|
||||||
name = expr['union']
|
name = expr['union']
|
||||||
|
base = expr['base']
|
||||||
|
tag_name = expr['discriminator']
|
||||||
data = expr['data']
|
data = expr['data']
|
||||||
base = expr.get('base')
|
|
||||||
ifcond = QAPISchemaIfCond(expr.get('if'))
|
ifcond = QAPISchemaIfCond(expr.get('if'))
|
||||||
features = self._make_features(expr.get('features'), info)
|
features = self._make_features(expr.get('features'), info)
|
||||||
tag_name = expr.get('discriminator')
|
|
||||||
tag_member = None
|
|
||||||
if isinstance(base, dict):
|
if isinstance(base, dict):
|
||||||
base = self._make_implicit_object_type(
|
base = self._make_implicit_object_type(
|
||||||
name, info, ifcond,
|
name, info, ifcond,
|
||||||
'base', self._make_members(base, info))
|
'base', self._make_members(base, info))
|
||||||
if tag_name:
|
variants = [
|
||||||
variants = [
|
self._make_variant(key, value['type'],
|
||||||
self._make_variant(key, value['type'],
|
QAPISchemaIfCond(value.get('if')),
|
||||||
QAPISchemaIfCond(value.get('if')),
|
info)
|
||||||
info)
|
for (key, value) in data.items()]
|
||||||
for (key, value) in data.items()]
|
members = []
|
||||||
members = []
|
|
||||||
else:
|
|
||||||
variants = [
|
|
||||||
self._make_simple_variant(key, value['type'],
|
|
||||||
QAPISchemaIfCond(value.get('if')),
|
|
||||||
info)
|
|
||||||
for (key, value) in data.items()]
|
|
||||||
enum = [{'name': v.name, 'if': v.ifcond.ifcond} for v in variants]
|
|
||||||
typ = self._make_implicit_enum_type(name, info, ifcond, enum)
|
|
||||||
tag_member = QAPISchemaObjectTypeMember('type', info, typ, False)
|
|
||||||
members = [tag_member]
|
|
||||||
self._def_entity(
|
self._def_entity(
|
||||||
QAPISchemaObjectType(name, info, doc, ifcond, features,
|
QAPISchemaObjectType(name, info, doc, ifcond, features,
|
||||||
base, members,
|
base, members,
|
||||||
QAPISchemaVariants(
|
QAPISchemaVariants(
|
||||||
tag_name, info, tag_member, variants)))
|
tag_name, info, None, variants)))
|
||||||
|
|
||||||
def _def_alternate_type(self, expr, info, doc):
|
def _def_alternate_type(self, expr, info, doc):
|
||||||
name = expr['alternate']
|
name = expr['alternate']
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
args-union.json: In command 'oops':
|
args-union.json: In command 'oops':
|
||||||
args-union.json:3: command's 'data' can take union type 'Uni' only with 'boxed': true
|
args-union.json:9: command's 'data' can take union type 'Uni' only with 'boxed': true
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
# use of union arguments requires 'boxed':true
|
# use of union arguments requires 'boxed':true
|
||||||
{ 'union': 'Uni', 'data': { 'case1': 'int', 'case2': 'str' } }
|
{ 'enum': 'Enum', 'data': [ 'case1', 'case2' ] }
|
||||||
|
{ 'struct': 'Case1', 'data': { 'data': 'int' } }
|
||||||
|
{ 'struct': 'Case2', 'data': { 'data': 'str' } }
|
||||||
|
{ 'union': 'Uni',
|
||||||
|
'base': { 'type': 'Enum' },
|
||||||
|
'discriminator': 'type',
|
||||||
|
'data': { 'case1': 'Case1', 'case2': 'Case2' } }
|
||||||
{ 'command': 'oops', 'data': 'Uni' }
|
{ 'command': 'oops', 'data': 'Uni' }
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
bad-base.json: In struct 'MyType':
|
bad-base.json: In struct 'MyType':
|
||||||
bad-base.json:3: 'base' requires a struct type, union type 'Union' isn't
|
bad-base.json:9: 'base' requires a struct type, union type 'Union' isn't
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
# we reject a base that is not a struct
|
# we reject a base that is not a struct
|
||||||
{ 'union': 'Union', 'data': { 'a': 'int', 'b': 'str' } }
|
{ 'enum': 'Enum', 'data': [ 'a', 'b' ] }
|
||||||
|
{ 'struct': 'Int', 'data': { 'data': 'int' } }
|
||||||
|
{ 'struct': 'Str', 'data': { 'data': 'str' } }
|
||||||
|
{ 'union': 'Union',
|
||||||
|
'base': { 'type': 'Enum' },
|
||||||
|
'discriminator': 'type',
|
||||||
|
'data': { 'a': 'Int', 'b': 'Str' } }
|
||||||
{ 'struct': 'MyType', 'base': 'Union', 'data': { 'c': 'int' } }
|
{ 'struct': 'MyType', 'base': 'Union', 'data': { 'c': 'int' } }
|
||||||
|
|
|
@ -60,8 +60,8 @@
|
||||||
#
|
#
|
||||||
# @two is undocumented
|
# @two is undocumented
|
||||||
##
|
##
|
||||||
{ 'enum': 'Enum', 'data':
|
{ 'enum': 'Enum',
|
||||||
[ { 'name': 'one', 'if': 'IFONE' }, 'two' ],
|
'data': [ { 'name': 'one', 'if': 'IFONE' }, 'two' ],
|
||||||
'features': [ 'enum-feat' ],
|
'features': [ 'enum-feat' ],
|
||||||
'if': 'IFCOND' }
|
'if': 'IFCOND' }
|
||||||
|
|
||||||
|
@ -107,15 +107,6 @@
|
||||||
'two': { 'type': 'Variant2',
|
'two': { 'type': 'Variant2',
|
||||||
'if': { 'any': ['IFONE', 'IFTWO'] } } } }
|
'if': { 'any': ['IFONE', 'IFTWO'] } } } }
|
||||||
|
|
||||||
##
|
|
||||||
# @SugaredUnion:
|
|
||||||
# Features:
|
|
||||||
# @union-feat2: a feature
|
|
||||||
##
|
|
||||||
{ 'union': 'SugaredUnion',
|
|
||||||
'features': [ 'union-feat2' ],
|
|
||||||
'data': { 'one': 'Variant1', 'two': { 'type': 'Variant2', 'if': 'IFTWO' } } }
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# @Alternate:
|
# @Alternate:
|
||||||
# @i: an integer
|
# @i: an integer
|
||||||
|
|
|
@ -32,21 +32,6 @@ object Object
|
||||||
case two: Variant2
|
case two: Variant2
|
||||||
if {'any': ['IFONE', 'IFTWO']}
|
if {'any': ['IFONE', 'IFTWO']}
|
||||||
feature union-feat1
|
feature union-feat1
|
||||||
object q_obj_Variant1-wrapper
|
|
||||||
member data: Variant1 optional=False
|
|
||||||
object q_obj_Variant2-wrapper
|
|
||||||
member data: Variant2 optional=False
|
|
||||||
enum SugaredUnionKind
|
|
||||||
member one
|
|
||||||
member two
|
|
||||||
if IFTWO
|
|
||||||
object SugaredUnion
|
|
||||||
member type: SugaredUnionKind optional=False
|
|
||||||
tag type
|
|
||||||
case one: q_obj_Variant1-wrapper
|
|
||||||
case two: q_obj_Variant2-wrapper
|
|
||||||
if IFTWO
|
|
||||||
feature union-feat2
|
|
||||||
alternate Alternate
|
alternate Alternate
|
||||||
tag type
|
tag type
|
||||||
case i: int
|
case i: int
|
||||||
|
@ -149,13 +134,6 @@ doc symbol=Object
|
||||||
|
|
||||||
feature=union-feat1
|
feature=union-feat1
|
||||||
a feature
|
a feature
|
||||||
doc symbol=SugaredUnion
|
|
||||||
body=
|
|
||||||
|
|
||||||
arg=type
|
|
||||||
|
|
||||||
feature=union-feat2
|
|
||||||
a feature
|
|
||||||
doc symbol=Alternate
|
doc symbol=Alternate
|
||||||
body=
|
body=
|
||||||
|
|
||||||
|
|
|
@ -130,26 +130,6 @@ Features
|
||||||
a feature
|
a feature
|
||||||
|
|
||||||
|
|
||||||
"SugaredUnion" (Object)
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
|
|
||||||
Members
|
|
||||||
~~~~~~~
|
|
||||||
|
|
||||||
"type"
|
|
||||||
One of "one", "two"
|
|
||||||
|
|
||||||
"data": "Variant1" when "type" is ""one""
|
|
||||||
"data": "Variant2" when "type" is ""two"" (**If: **"IFTWO")
|
|
||||||
|
|
||||||
Features
|
|
||||||
~~~~~~~~
|
|
||||||
|
|
||||||
"union-feat2"
|
|
||||||
a feature
|
|
||||||
|
|
||||||
|
|
||||||
"Alternate" (Alternate)
|
"Alternate" (Alternate)
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
# check invalid 'if' type
|
# check invalid 'if' type
|
||||||
{ 'enum': 'TestIfEnum', 'data':
|
{ 'enum': 'TestIfEnum',
|
||||||
[ 'foo', { 'name' : 'bar', 'if': { 'val': 'foo' } } ] }
|
'data': [ 'foo', { 'name' : 'bar', 'if': { 'val': 'foo' } } ] }
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
flat-union-array-branch.json: In union 'TestUnion':
|
|
||||||
flat-union-array-branch.json:8: 'data' member 'value1' cannot be an array
|
|
|
@ -1,2 +0,0 @@
|
||||||
flat-union-bad-base.json: In union 'TestUnion':
|
|
||||||
flat-union-bad-base.json:8: member 'string' of type 'TestTypeA' collides with base member 'string'
|
|
|
@ -1,2 +0,0 @@
|
||||||
flat-union-bad-discriminator.json: In union 'TestUnion':
|
|
||||||
flat-union-bad-discriminator.json:11: 'discriminator' requires a string name
|
|
|
@ -1,2 +0,0 @@
|
||||||
flat-union-base-any.json: In union 'TestUnion':
|
|
||||||
flat-union-base-any.json:8: 'base' requires a struct type, built-in type 'any' isn't
|
|
|
@ -1,2 +0,0 @@
|
||||||
flat-union-base-union.json: In union 'TestUnion':
|
|
||||||
flat-union-base-union.json:14: 'base' requires a struct type, union type 'UnionBase' isn't
|
|
|
@ -1,2 +0,0 @@
|
||||||
flat-union-clash-member.json: In union 'TestUnion':
|
|
||||||
flat-union-clash-member.json:11: member 'name' of type 'Branch1' collides with member 'name' of type 'Base'
|
|
|
@ -1,2 +0,0 @@
|
||||||
flat-union-discriminator-bad-name.json: In union 'MyUnion':
|
|
||||||
flat-union-discriminator-bad-name.json:6: discriminator '*switch' is not a member of 'base'
|
|
|
@ -1,2 +0,0 @@
|
||||||
flat-union-empty.json: In union 'Union':
|
|
||||||
flat-union-empty.json:4: union has no branches
|
|
|
@ -1,4 +0,0 @@
|
||||||
# flat union discriminator cannot be empty
|
|
||||||
{ 'enum': 'Empty', 'data': [ ] }
|
|
||||||
{ 'struct': 'Base', 'data': { 'type': 'Empty' } }
|
|
||||||
{ 'union': 'Union', 'base': 'Base', 'discriminator': 'type', 'data': { } }
|
|
|
@ -1,2 +0,0 @@
|
||||||
flat-union-inline-invalid-dict.json: In union 'TestUnion':
|
|
||||||
flat-union-inline-invalid-dict.json:7: 'data' member 'value1' misses key 'type'
|
|
|
@ -1,2 +0,0 @@
|
||||||
flat-union-int-branch.json: In union 'TestUnion':
|
|
||||||
flat-union-int-branch.json:8: branch 'value1' cannot use built-in type 'int'
|
|
|
@ -1,2 +0,0 @@
|
||||||
flat-union-invalid-branch-key.json: In union 'TestUnion':
|
|
||||||
flat-union-invalid-branch-key.json:13: branch 'value_wrong' is not a value of enum type 'TestEnum'
|
|
|
@ -1,2 +0,0 @@
|
||||||
flat-union-invalid-discriminator.json: In union 'TestUnion':
|
|
||||||
flat-union-invalid-discriminator.json:10: discriminator 'enum_wrong' is not a member of 'base'
|
|
|
@ -1,2 +0,0 @@
|
||||||
flat-union-invalid-if-discriminator.json: In union 'TestUnion':
|
|
||||||
flat-union-invalid-if-discriminator.json:10: discriminator member 'enum1' of 'base' must not be conditional
|
|
|
@ -1,2 +0,0 @@
|
||||||
flat-union-no-base.json: In union 'TestUnion':
|
|
||||||
flat-union-no-base.json:8: 'discriminator' requires 'base'
|
|
|
@ -1,2 +0,0 @@
|
||||||
flat-union-optional-discriminator.json: In union 'MyUnion':
|
|
||||||
flat-union-optional-discriminator.json:6: discriminator member 'switch' of base type 'Base' must not be optional
|
|
|
@ -1,2 +0,0 @@
|
||||||
flat-union-string-discriminator.json: In union 'TestUnion':
|
|
||||||
flat-union-string-discriminator.json:13: discriminator member 'kind' of base type 'TestBase' must be of enum type
|
|
|
@ -107,22 +107,6 @@ schemas = [
|
||||||
'features-name-bad-type.json',
|
'features-name-bad-type.json',
|
||||||
'features-no-list.json',
|
'features-no-list.json',
|
||||||
'features-unknown-key.json',
|
'features-unknown-key.json',
|
||||||
'flat-union-array-branch.json',
|
|
||||||
'flat-union-bad-base.json',
|
|
||||||
'flat-union-bad-discriminator.json',
|
|
||||||
'flat-union-base-any.json',
|
|
||||||
'flat-union-base-union.json',
|
|
||||||
'flat-union-clash-member.json',
|
|
||||||
'flat-union-discriminator-bad-name.json',
|
|
||||||
'flat-union-empty.json',
|
|
||||||
'flat-union-inline-invalid-dict.json',
|
|
||||||
'flat-union-int-branch.json',
|
|
||||||
'flat-union-invalid-branch-key.json',
|
|
||||||
'flat-union-invalid-discriminator.json',
|
|
||||||
'flat-union-invalid-if-discriminator.json',
|
|
||||||
'flat-union-no-base.json',
|
|
||||||
'flat-union-optional-discriminator.json',
|
|
||||||
'flat-union-string-discriminator.json',
|
|
||||||
'funny-char.json',
|
'funny-char.json',
|
||||||
'funny-word.json',
|
'funny-word.json',
|
||||||
'ident-with-escape.json',
|
'ident-with-escape.json',
|
||||||
|
@ -168,7 +152,6 @@ schemas = [
|
||||||
'reserved-member-q.json',
|
'reserved-member-q.json',
|
||||||
'reserved-member-u.json',
|
'reserved-member-u.json',
|
||||||
'reserved-member-underscore.json',
|
'reserved-member-underscore.json',
|
||||||
'reserved-type-kind.json',
|
|
||||||
'reserved-type-list.json',
|
'reserved-type-list.json',
|
||||||
'returns-alternate.json',
|
'returns-alternate.json',
|
||||||
'returns-array-bad.json',
|
'returns-array-bad.json',
|
||||||
|
@ -191,16 +174,28 @@ schemas = [
|
||||||
'unclosed-list.json',
|
'unclosed-list.json',
|
||||||
'unclosed-object.json',
|
'unclosed-object.json',
|
||||||
'unclosed-string.json',
|
'unclosed-string.json',
|
||||||
|
'union-array-branch.json',
|
||||||
|
'union-bad-base.json',
|
||||||
|
'union-bad-discriminator.json',
|
||||||
|
'union-base-any.json',
|
||||||
'union-base-empty.json',
|
'union-base-empty.json',
|
||||||
'union-base-no-discriminator.json',
|
'union-base-no-discriminator.json',
|
||||||
'union-branch-case.json',
|
'union-base-union.json',
|
||||||
'union-branch-if-invalid.json',
|
'union-branch-if-invalid.json',
|
||||||
'union-branch-invalid-dict.json',
|
'union-branch-invalid-dict.json',
|
||||||
'union-clash-branches.json',
|
'union-clash-member.json',
|
||||||
|
'union-discriminator-bad-name.json',
|
||||||
'union-empty.json',
|
'union-empty.json',
|
||||||
|
'union-inline-invalid-dict.json',
|
||||||
|
'union-int-branch.json',
|
||||||
'union-invalid-base.json',
|
'union-invalid-base.json',
|
||||||
|
'union-invalid-branch-key.json',
|
||||||
'union-invalid-data.json',
|
'union-invalid-data.json',
|
||||||
'union-optional-branch.json',
|
'union-invalid-discriminator.json',
|
||||||
|
'union-invalid-if-discriminator.json',
|
||||||
|
'union-no-base.json',
|
||||||
|
'union-optional-discriminator.json',
|
||||||
|
'union-string-discriminator.json',
|
||||||
'union-unknown.json',
|
'union-unknown.json',
|
||||||
'unknown-escape.json',
|
'unknown-escape.json',
|
||||||
'unknown-expr-key.json',
|
'unknown-expr-key.json',
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
{ 'struct': 'Empty1', 'data': { } }
|
{ 'struct': 'Empty1', 'data': { } }
|
||||||
{ 'struct': 'Empty2', 'base': 'Empty1', 'data': { } }
|
{ 'struct': 'Empty2', 'base': 'Empty1', 'data': { } }
|
||||||
|
|
||||||
# Likewise for an empty flat union
|
# Likewise for an empty union
|
||||||
{ 'union': 'Union',
|
{ 'union': 'Union',
|
||||||
'base': { 'type': 'EnumOne' }, 'discriminator': 'type',
|
'base': { 'type': 'EnumOne' }, 'discriminator': 'type',
|
||||||
'data': { } }
|
'data': { } }
|
||||||
|
@ -123,8 +123,7 @@
|
||||||
# for testing use of 'str' within alternates
|
# for testing use of 'str' within alternates
|
||||||
{ 'alternate': 'AltStrObj', 'data': { 's': 'str', 'o': 'TestStruct' } }
|
{ 'alternate': 'AltStrObj', 'data': { 's': 'str', 'o': 'TestStruct' } }
|
||||||
|
|
||||||
# for testing lists
|
{ 'struct': 'ArrayStruct',
|
||||||
{ 'union': 'UserDefListUnion',
|
|
||||||
'data': { 'integer': ['int'],
|
'data': { 'integer': ['int'],
|
||||||
's8': ['int8'],
|
's8': ['int8'],
|
||||||
's16': ['int16'],
|
's16': ['int16'],
|
||||||
|
@ -137,9 +136,9 @@
|
||||||
'number': ['number'],
|
'number': ['number'],
|
||||||
'boolean': ['bool'],
|
'boolean': ['bool'],
|
||||||
'string': ['str'],
|
'string': ['str'],
|
||||||
'sizes': ['size'],
|
'*sz': ['size'],
|
||||||
'any': ['any'],
|
'*any': ['any'],
|
||||||
'user': ['Status'] } } # intentional forward ref. to sub-module
|
'*user': ['Status'] } } # intentional forward ref. to sub-module
|
||||||
|
|
||||||
# for testing sub-modules
|
# for testing sub-modules
|
||||||
{ 'include': 'include/sub-module.json' }
|
{ 'include': 'include/sub-module.json' }
|
||||||
|
@ -159,7 +158,7 @@
|
||||||
'returns': 'int' }
|
'returns': 'int' }
|
||||||
{ 'command': 'guest-sync', 'data': { 'arg': 'any' }, 'returns': 'any' }
|
{ 'command': 'guest-sync', 'data': { 'arg': 'any' }, 'returns': 'any' }
|
||||||
{ 'command': 'boxed-struct', 'boxed': true, 'data': 'UserDefZero' }
|
{ 'command': 'boxed-struct', 'boxed': true, 'data': 'UserDefZero' }
|
||||||
{ 'command': 'boxed-union', 'data': 'UserDefListUnion', 'boxed': true }
|
{ 'command': 'boxed-union', 'data': 'UserDefFlatUnion', 'boxed': true }
|
||||||
{ 'command': 'boxed-empty', 'boxed': true, 'data': 'Empty1' }
|
{ 'command': 'boxed-empty', 'boxed': true, 'data': 'Empty1' }
|
||||||
|
|
||||||
# Smoke test on out-of-band and allow-preconfig-test
|
# Smoke test on out-of-band and allow-preconfig-test
|
||||||
|
@ -203,11 +202,10 @@
|
||||||
'data': { '__org.qemu_x-member1': '__org.qemu_x-Enum' } }
|
'data': { '__org.qemu_x-member1': '__org.qemu_x-Enum' } }
|
||||||
{ 'struct': '__org.qemu_x-Struct', 'base': '__org.qemu_x-Base',
|
{ 'struct': '__org.qemu_x-Struct', 'base': '__org.qemu_x-Base',
|
||||||
'data': { '__org.qemu_x-member2': 'str', '*wchar-t': 'int' } }
|
'data': { '__org.qemu_x-member2': 'str', '*wchar-t': 'int' } }
|
||||||
{ 'union': '__org.qemu_x-Union1', 'data': { '__org.qemu_x-branch': 'str' } }
|
|
||||||
{ 'alternate': '__org.qemu_x-Alt1', 'data': { '__org.qemu_x-branch': 'str' } }
|
{ 'alternate': '__org.qemu_x-Alt1', 'data': { '__org.qemu_x-branch': 'str' } }
|
||||||
{ 'struct': '__org.qemu_x-Struct2',
|
{ 'struct': '__org.qemu_x-Struct2',
|
||||||
'data': { 'array': ['__org.qemu_x-Union1'] } }
|
'data': { 'array': ['__org.qemu_x-Union'] } }
|
||||||
{ 'union': '__org.qemu_x-Union2', 'base': '__org.qemu_x-Base',
|
{ 'union': '__org.qemu_x-Union', 'base': '__org.qemu_x-Base',
|
||||||
'discriminator': '__org.qemu_x-member1',
|
'discriminator': '__org.qemu_x-member1',
|
||||||
'data': { '__org.qemu_x-value': '__org.qemu_x-Struct2' } }
|
'data': { '__org.qemu_x-value': '__org.qemu_x-Struct2' } }
|
||||||
{ 'alternate': '__org.qemu_x-Alt',
|
{ 'alternate': '__org.qemu_x-Alt',
|
||||||
|
@ -215,32 +213,33 @@
|
||||||
{ 'event': '__ORG.QEMU_X-EVENT', 'data': '__org.qemu_x-Struct' }
|
{ 'event': '__ORG.QEMU_X-EVENT', 'data': '__org.qemu_x-Struct' }
|
||||||
{ 'command': '__org.qemu_x-command',
|
{ 'command': '__org.qemu_x-command',
|
||||||
'data': { 'a': ['__org.qemu_x-Enum'], 'b': ['__org.qemu_x-Struct'],
|
'data': { 'a': ['__org.qemu_x-Enum'], 'b': ['__org.qemu_x-Struct'],
|
||||||
'c': '__org.qemu_x-Union2', 'd': '__org.qemu_x-Alt' },
|
'c': '__org.qemu_x-Union', 'd': '__org.qemu_x-Alt' } }
|
||||||
'returns': '__org.qemu_x-Union1' }
|
|
||||||
|
|
||||||
# test 'if' condition handling
|
# test 'if' condition handling
|
||||||
|
|
||||||
{ 'struct': 'TestIfStruct', 'data':
|
{ 'struct': 'TestIfStruct',
|
||||||
{ 'foo': 'int',
|
'data': { 'foo': 'int',
|
||||||
'bar': { 'type': 'int', 'if': 'TEST_IF_STRUCT_BAR'} },
|
'bar': { 'type': 'int', 'if': 'TEST_IF_STRUCT_BAR'} },
|
||||||
'if': 'TEST_IF_STRUCT' }
|
'if': 'TEST_IF_STRUCT' }
|
||||||
|
|
||||||
{ 'enum': 'TestIfEnum', 'data':
|
{ 'enum': 'TestIfEnum',
|
||||||
[ 'foo', { 'name' : 'bar', 'if': 'TEST_IF_ENUM_BAR' } ],
|
'data': [ 'foo', { 'name' : 'bar', 'if': 'TEST_IF_ENUM_BAR' } ],
|
||||||
'if': 'TEST_IF_ENUM' }
|
'if': 'TEST_IF_ENUM' }
|
||||||
|
|
||||||
{ 'union': 'TestIfUnion', 'data':
|
{ 'union': 'TestIfUnion',
|
||||||
{ 'foo': 'TestStruct',
|
'base': { 'type': 'TestIfEnum' },
|
||||||
'bar': { 'type': 'str', 'if': 'TEST_IF_UNION_BAR'} },
|
'discriminator': 'type',
|
||||||
|
'data': { 'foo': 'TestStruct',
|
||||||
|
'bar': { 'type': 'UserDefZero', 'if': 'TEST_IF_ENUM_BAR'} },
|
||||||
'if': { 'all': ['TEST_IF_UNION', 'TEST_IF_STRUCT'] } }
|
'if': { 'all': ['TEST_IF_UNION', 'TEST_IF_STRUCT'] } }
|
||||||
|
|
||||||
{ 'command': 'test-if-union-cmd',
|
{ 'command': 'test-if-union-cmd',
|
||||||
'data': { 'union-cmd-arg': 'TestIfUnion' },
|
'data': { 'union-cmd-arg': 'TestIfUnion' },
|
||||||
'if': { 'all': ['TEST_IF_UNION', 'TEST_IF_STRUCT'] } }
|
'if': { 'all': ['TEST_IF_UNION', 'TEST_IF_STRUCT'] } }
|
||||||
|
|
||||||
{ 'alternate': 'TestIfAlternate', 'data':
|
{ 'alternate': 'TestIfAlternate',
|
||||||
{ 'foo': 'int',
|
'data': { 'foo': 'int',
|
||||||
'bar': { 'type': 'TestStruct', 'if': 'TEST_IF_ALT_BAR'} },
|
'bar': { 'type': 'TestStruct', 'if': 'TEST_IF_ALT_BAR'} },
|
||||||
'if': { 'all': ['TEST_IF_ALT', 'TEST_IF_STRUCT'] } }
|
'if': { 'all': ['TEST_IF_ALT', 'TEST_IF_STRUCT'] } }
|
||||||
|
|
||||||
{ 'command': 'test-if-alternate-cmd',
|
{ 'command': 'test-if-alternate-cmd',
|
||||||
|
@ -256,9 +255,9 @@
|
||||||
|
|
||||||
{ 'command': 'test-cmd-return-def-three', 'returns': 'UserDefThree' }
|
{ 'command': 'test-cmd-return-def-three', 'returns': 'UserDefThree' }
|
||||||
|
|
||||||
{ 'event': 'TEST_IF_EVENT', 'data':
|
{ 'event': 'TEST_IF_EVENT',
|
||||||
{ 'foo': 'TestIfStruct',
|
'data': { 'foo': 'TestIfStruct',
|
||||||
'bar': { 'type': ['TestIfEnum'], 'if': 'TEST_IF_EVT_BAR' } },
|
'bar': { 'type': ['TestIfEnum'], 'if': 'TEST_IF_EVT_BAR' } },
|
||||||
'if': { 'all': ['TEST_IF_EVT', 'TEST_IF_STRUCT'] } }
|
'if': { 'all': ['TEST_IF_EVT', 'TEST_IF_STRUCT'] } }
|
||||||
|
|
||||||
{ 'event': 'TEST_IF_EVENT2', 'data': {},
|
{ 'event': 'TEST_IF_EVENT2', 'data': {},
|
||||||
|
|
|
@ -125,70 +125,22 @@ alternate AltStrObj
|
||||||
tag type
|
tag type
|
||||||
case s: str
|
case s: str
|
||||||
case o: TestStruct
|
case o: TestStruct
|
||||||
object q_obj_intList-wrapper
|
object ArrayStruct
|
||||||
member data: intList optional=False
|
member integer: intList optional=False
|
||||||
object q_obj_int8List-wrapper
|
member s8: int8List optional=False
|
||||||
member data: int8List optional=False
|
member s16: int16List optional=False
|
||||||
object q_obj_int16List-wrapper
|
member s32: int32List optional=False
|
||||||
member data: int16List optional=False
|
member s64: int64List optional=False
|
||||||
object q_obj_int32List-wrapper
|
member u8: uint8List optional=False
|
||||||
member data: int32List optional=False
|
member u16: uint16List optional=False
|
||||||
object q_obj_int64List-wrapper
|
member u32: uint32List optional=False
|
||||||
member data: int64List optional=False
|
member u64: uint64List optional=False
|
||||||
object q_obj_uint8List-wrapper
|
member number: numberList optional=False
|
||||||
member data: uint8List optional=False
|
member boolean: boolList optional=False
|
||||||
object q_obj_uint16List-wrapper
|
member string: strList optional=False
|
||||||
member data: uint16List optional=False
|
member sz: sizeList optional=True
|
||||||
object q_obj_uint32List-wrapper
|
member any: anyList optional=True
|
||||||
member data: uint32List optional=False
|
member user: StatusList optional=True
|
||||||
object q_obj_uint64List-wrapper
|
|
||||||
member data: uint64List optional=False
|
|
||||||
object q_obj_numberList-wrapper
|
|
||||||
member data: numberList optional=False
|
|
||||||
object q_obj_boolList-wrapper
|
|
||||||
member data: boolList optional=False
|
|
||||||
object q_obj_strList-wrapper
|
|
||||||
member data: strList optional=False
|
|
||||||
object q_obj_sizeList-wrapper
|
|
||||||
member data: sizeList optional=False
|
|
||||||
object q_obj_anyList-wrapper
|
|
||||||
member data: anyList optional=False
|
|
||||||
object q_obj_StatusList-wrapper
|
|
||||||
member data: StatusList optional=False
|
|
||||||
enum UserDefListUnionKind
|
|
||||||
member integer
|
|
||||||
member s8
|
|
||||||
member s16
|
|
||||||
member s32
|
|
||||||
member s64
|
|
||||||
member u8
|
|
||||||
member u16
|
|
||||||
member u32
|
|
||||||
member u64
|
|
||||||
member number
|
|
||||||
member boolean
|
|
||||||
member string
|
|
||||||
member sizes
|
|
||||||
member any
|
|
||||||
member user
|
|
||||||
object UserDefListUnion
|
|
||||||
member type: UserDefListUnionKind optional=False
|
|
||||||
tag type
|
|
||||||
case integer: q_obj_intList-wrapper
|
|
||||||
case s8: q_obj_int8List-wrapper
|
|
||||||
case s16: q_obj_int16List-wrapper
|
|
||||||
case s32: q_obj_int32List-wrapper
|
|
||||||
case s64: q_obj_int64List-wrapper
|
|
||||||
case u8: q_obj_uint8List-wrapper
|
|
||||||
case u16: q_obj_uint16List-wrapper
|
|
||||||
case u32: q_obj_uint32List-wrapper
|
|
||||||
case u64: q_obj_uint64List-wrapper
|
|
||||||
case number: q_obj_numberList-wrapper
|
|
||||||
case boolean: q_obj_boolList-wrapper
|
|
||||||
case string: q_obj_strList-wrapper
|
|
||||||
case sizes: q_obj_sizeList-wrapper
|
|
||||||
case any: q_obj_anyList-wrapper
|
|
||||||
case user: q_obj_StatusList-wrapper
|
|
||||||
include include/sub-module.json
|
include include/sub-module.json
|
||||||
command user-def-cmd None -> None
|
command user-def-cmd None -> None
|
||||||
gen=True success_response=True boxed=False oob=False preconfig=False
|
gen=True success_response=True boxed=False oob=False preconfig=False
|
||||||
|
@ -216,7 +168,7 @@ command guest-sync q_obj_guest-sync-arg -> any
|
||||||
gen=True success_response=True boxed=False oob=False preconfig=False
|
gen=True success_response=True boxed=False oob=False preconfig=False
|
||||||
command boxed-struct UserDefZero -> None
|
command boxed-struct UserDefZero -> None
|
||||||
gen=True success_response=True boxed=True oob=False preconfig=False
|
gen=True success_response=True boxed=True oob=False preconfig=False
|
||||||
command boxed-union UserDefListUnion -> None
|
command boxed-union UserDefFlatUnion -> None
|
||||||
gen=True success_response=True boxed=True oob=False preconfig=False
|
gen=True success_response=True boxed=True oob=False preconfig=False
|
||||||
command boxed-empty Empty1 -> None
|
command boxed-empty Empty1 -> None
|
||||||
gen=True success_response=True boxed=True oob=False preconfig=False
|
gen=True success_response=True boxed=True oob=False preconfig=False
|
||||||
|
@ -263,21 +215,13 @@ object __org.qemu_x-Struct
|
||||||
base __org.qemu_x-Base
|
base __org.qemu_x-Base
|
||||||
member __org.qemu_x-member2: str optional=False
|
member __org.qemu_x-member2: str optional=False
|
||||||
member wchar-t: int optional=True
|
member wchar-t: int optional=True
|
||||||
object q_obj_str-wrapper
|
|
||||||
member data: str optional=False
|
|
||||||
enum __org.qemu_x-Union1Kind
|
|
||||||
member __org.qemu_x-branch
|
|
||||||
object __org.qemu_x-Union1
|
|
||||||
member type: __org.qemu_x-Union1Kind optional=False
|
|
||||||
tag type
|
|
||||||
case __org.qemu_x-branch: q_obj_str-wrapper
|
|
||||||
alternate __org.qemu_x-Alt1
|
alternate __org.qemu_x-Alt1
|
||||||
tag type
|
tag type
|
||||||
case __org.qemu_x-branch: str
|
case __org.qemu_x-branch: str
|
||||||
array __org.qemu_x-Union1List __org.qemu_x-Union1
|
array __org.qemu_x-UnionList __org.qemu_x-Union
|
||||||
object __org.qemu_x-Struct2
|
object __org.qemu_x-Struct2
|
||||||
member array: __org.qemu_x-Union1List optional=False
|
member array: __org.qemu_x-UnionList optional=False
|
||||||
object __org.qemu_x-Union2
|
object __org.qemu_x-Union
|
||||||
base __org.qemu_x-Base
|
base __org.qemu_x-Base
|
||||||
tag __org.qemu_x-member1
|
tag __org.qemu_x-member1
|
||||||
case __org.qemu_x-value: __org.qemu_x-Struct2
|
case __org.qemu_x-value: __org.qemu_x-Struct2
|
||||||
|
@ -291,9 +235,9 @@ array __org.qemu_x-StructList __org.qemu_x-Struct
|
||||||
object q_obj___org.qemu_x-command-arg
|
object q_obj___org.qemu_x-command-arg
|
||||||
member a: __org.qemu_x-EnumList optional=False
|
member a: __org.qemu_x-EnumList optional=False
|
||||||
member b: __org.qemu_x-StructList optional=False
|
member b: __org.qemu_x-StructList optional=False
|
||||||
member c: __org.qemu_x-Union2 optional=False
|
member c: __org.qemu_x-Union optional=False
|
||||||
member d: __org.qemu_x-Alt optional=False
|
member d: __org.qemu_x-Alt optional=False
|
||||||
command __org.qemu_x-command q_obj___org.qemu_x-command-arg -> __org.qemu_x-Union1
|
command __org.qemu_x-command q_obj___org.qemu_x-command-arg -> None
|
||||||
gen=True success_response=True boxed=False oob=False preconfig=False
|
gen=True success_response=True boxed=False oob=False preconfig=False
|
||||||
object TestIfStruct
|
object TestIfStruct
|
||||||
member foo: int optional=False
|
member foo: int optional=False
|
||||||
|
@ -305,19 +249,15 @@ enum TestIfEnum
|
||||||
member bar
|
member bar
|
||||||
if TEST_IF_ENUM_BAR
|
if TEST_IF_ENUM_BAR
|
||||||
if TEST_IF_ENUM
|
if TEST_IF_ENUM
|
||||||
object q_obj_TestStruct-wrapper
|
object q_obj_TestIfUnion-base
|
||||||
member data: TestStruct optional=False
|
member type: TestIfEnum optional=False
|
||||||
enum TestIfUnionKind
|
|
||||||
member foo
|
|
||||||
member bar
|
|
||||||
if TEST_IF_UNION_BAR
|
|
||||||
if {'all': ['TEST_IF_UNION', 'TEST_IF_STRUCT']}
|
if {'all': ['TEST_IF_UNION', 'TEST_IF_STRUCT']}
|
||||||
object TestIfUnion
|
object TestIfUnion
|
||||||
member type: TestIfUnionKind optional=False
|
base q_obj_TestIfUnion-base
|
||||||
tag type
|
tag type
|
||||||
case foo: q_obj_TestStruct-wrapper
|
case foo: TestStruct
|
||||||
case bar: q_obj_str-wrapper
|
case bar: UserDefZero
|
||||||
if TEST_IF_UNION_BAR
|
if TEST_IF_ENUM_BAR
|
||||||
if {'all': ['TEST_IF_UNION', 'TEST_IF_STRUCT']}
|
if {'all': ['TEST_IF_UNION', 'TEST_IF_STRUCT']}
|
||||||
object q_obj_test-if-union-cmd-arg
|
object q_obj_test-if-union-cmd-arg
|
||||||
member union-cmd-arg: TestIfUnion optional=False
|
member union-cmd-arg: TestIfUnion optional=False
|
||||||
|
|
|
@ -2,6 +2,6 @@
|
||||||
# We reject use of 'u' as a member name, to allow it for internal use in
|
# We reject use of 'u' as a member name, to allow it for internal use in
|
||||||
# putting union branch members in a separate namespace from QMP members.
|
# putting union branch members in a separate namespace from QMP members.
|
||||||
# This is true even for non-unions, because it is possible to convert a
|
# This is true even for non-unions, because it is possible to convert a
|
||||||
# struct to flat union while remaining backwards compatible in QMP.
|
# struct to union while remaining backwards compatible in QMP.
|
||||||
# TODO - we could munge the member name to 'q_u' to avoid the collision
|
# TODO - we could munge the member name to 'q_u' to avoid the collision
|
||||||
{ 'struct': 'Oops', 'data': { '*u': 'str' } }
|
{ 'struct': 'Oops', 'data': { '*u': 'str' } }
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
reserved-type-kind.json: In enum 'UnionKind':
|
|
||||||
reserved-type-kind.json:2: enum name should not end in 'Kind'
|
|
|
@ -1,2 +0,0 @@
|
||||||
# we reject types that would conflict with implicit union enum
|
|
||||||
{ 'enum': 'UnionKind', 'data': [ 'oops' ] }
|
|
|
@ -132,6 +132,17 @@ def test_frontend(fname):
|
||||||
print(' section=%s\n%s' % (section.name, section.text))
|
print(' section=%s\n%s' % (section.name, section.text))
|
||||||
|
|
||||||
|
|
||||||
|
def open_test_result(dir_name, file_name, update):
|
||||||
|
mode = 'r+' if update else 'r'
|
||||||
|
try:
|
||||||
|
fp = open(os.path.join(dir_name, file_name), mode)
|
||||||
|
except FileNotFoundError:
|
||||||
|
if not update:
|
||||||
|
raise
|
||||||
|
fp = open(os.path.join(dir_name, file_name), 'w+')
|
||||||
|
return fp
|
||||||
|
|
||||||
|
|
||||||
def test_and_diff(test_name, dir_name, update):
|
def test_and_diff(test_name, dir_name, update):
|
||||||
sys.stdout = StringIO()
|
sys.stdout = StringIO()
|
||||||
try:
|
try:
|
||||||
|
@ -148,13 +159,12 @@ def test_and_diff(test_name, dir_name, update):
|
||||||
sys.stdout.close()
|
sys.stdout.close()
|
||||||
sys.stdout = sys.__stdout__
|
sys.stdout = sys.__stdout__
|
||||||
|
|
||||||
mode = 'r+' if update else 'r'
|
|
||||||
try:
|
try:
|
||||||
outfp = open(os.path.join(dir_name, test_name + '.out'), mode)
|
outfp = open_test_result(dir_name, test_name + '.out', update)
|
||||||
errfp = open(os.path.join(dir_name, test_name + '.err'), mode)
|
errfp = open_test_result(dir_name, test_name + '.err', update)
|
||||||
expected_out = outfp.readlines()
|
expected_out = outfp.readlines()
|
||||||
expected_err = errfp.readlines()
|
expected_err = errfp.readlines()
|
||||||
except IOError as err:
|
except OSError as err:
|
||||||
print("%s: can't open '%s': %s"
|
print("%s: can't open '%s': %s"
|
||||||
% (sys.argv[0], err.filename, err.strerror),
|
% (sys.argv[0], err.filename, err.strerror),
|
||||||
file=sys.stderr)
|
file=sys.stderr)
|
||||||
|
@ -180,7 +190,7 @@ def test_and_diff(test_name, dir_name, update):
|
||||||
errfp.truncate(0)
|
errfp.truncate(0)
|
||||||
errfp.seek(0)
|
errfp.seek(0)
|
||||||
errfp.writelines(actual_err)
|
errfp.writelines(actual_err)
|
||||||
except IOError as err:
|
except OSError as err:
|
||||||
print("%s: can't write '%s': %s"
|
print("%s: can't write '%s': %s"
|
||||||
% (sys.argv[0], err.filename, err.strerror),
|
% (sys.argv[0], err.filename, err.strerror),
|
||||||
file=sys.stderr)
|
file=sys.stderr)
|
||||||
|
|
2
tests/qapi-schema/union-array-branch.err
Normal file
2
tests/qapi-schema/union-array-branch.err
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
union-array-branch.json: In union 'TestUnion':
|
||||||
|
union-array-branch.json:8: 'data' member 'value1' cannot be an array
|
|
@ -1,4 +1,4 @@
|
||||||
# we require flat union branches to be a struct
|
# we require union branches to be a struct
|
||||||
{ 'enum': 'TestEnum',
|
{ 'enum': 'TestEnum',
|
||||||
'data': [ 'value1', 'value2' ] }
|
'data': [ 'value1', 'value2' ] }
|
||||||
{ 'struct': 'Base',
|
{ 'struct': 'Base',
|
2
tests/qapi-schema/union-bad-base.err
Normal file
2
tests/qapi-schema/union-bad-base.err
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
union-bad-base.json: In union 'TestUnion':
|
||||||
|
union-bad-base.json:8: member 'string' of type 'TestTypeA' collides with base member 'string'
|
2
tests/qapi-schema/union-bad-discriminator.err
Normal file
2
tests/qapi-schema/union-bad-discriminator.err
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
union-bad-discriminator.json: In union 'TestUnion':
|
||||||
|
union-bad-discriminator.json:11: 'discriminator' requires a string name
|
2
tests/qapi-schema/union-base-any.err
Normal file
2
tests/qapi-schema/union-base-any.err
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
union-base-any.json: In union 'TestUnion':
|
||||||
|
union-base-any.json:8: 'base' requires a struct type, built-in type 'any' isn't
|
|
@ -1,4 +1,4 @@
|
||||||
# Flat union with empty base and therefore without discriminator
|
# Union with empty base and therefore without discriminator
|
||||||
|
|
||||||
{ 'struct': 'Empty', 'data': { } }
|
{ 'struct': 'Empty', 'data': { } }
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
union-base-no-discriminator.json: In union 'TestUnion':
|
union-base-no-discriminator.json: In union 'TestUnion':
|
||||||
union-base-no-discriminator.json:11: 'base' requires 'discriminator'
|
union-base-no-discriminator.json:11: union misses key 'discriminator'
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# we reject simple unions with a base (or flat unions without discriminator)
|
# we reject unions without discriminator
|
||||||
{ 'struct': 'TestTypeA',
|
{ 'struct': 'TestTypeA',
|
||||||
'data': { 'string': 'str' } }
|
'data': { 'string': 'str' } }
|
||||||
|
|
||||||
|
|
2
tests/qapi-schema/union-base-union.err
Normal file
2
tests/qapi-schema/union-base-union.err
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
union-base-union.json: In union 'TestUnion':
|
||||||
|
union-base-union.json:17: 'base' requires a struct type, union type 'UnionBase' isn't
|
|
@ -8,7 +8,10 @@
|
||||||
'data': { 'string': 'str' } }
|
'data': { 'string': 'str' } }
|
||||||
{ 'struct': 'TestTypeB',
|
{ 'struct': 'TestTypeB',
|
||||||
'data': { 'integer': 'int' } }
|
'data': { 'integer': 'int' } }
|
||||||
|
{ 'enum': 'Enum', 'data': [ 'kind1', 'kind2' ] }
|
||||||
{ 'union': 'UnionBase',
|
{ 'union': 'UnionBase',
|
||||||
|
'base': { 'type': 'Enum' },
|
||||||
|
'discriminator': 'type',
|
||||||
'data': { 'kind1': 'TestTypeA',
|
'data': { 'kind1': 'TestTypeA',
|
||||||
'kind2': 'TestTypeB' } }
|
'kind2': 'TestTypeB' } }
|
||||||
{ 'union': 'TestUnion',
|
{ 'union': 'TestUnion',
|
|
@ -1,2 +0,0 @@
|
||||||
union-branch-case.json: In union 'Uni':
|
|
||||||
union-branch-case.json:2: name of 'data' member 'Branch' must not use uppercase or '_'
|
|
|
@ -1,2 +0,0 @@
|
||||||
# Branch names should be 'lower-case'
|
|
||||||
{ 'union': 'Uni', 'data': { 'Branch': 'int' } }
|
|
|
@ -1,2 +1,2 @@
|
||||||
union-branch-invalid-dict.json: In union 'UnionInvalidBranch':
|
union-branch-invalid-dict.json: In union 'UnionInvalidBranch':
|
||||||
union-branch-invalid-dict.json:2: 'data' member 'integer' misses key 'type'
|
union-branch-invalid-dict.json:4: 'data' member 'integer' misses key 'type'
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
# Long form of member must have a value member 'type'
|
# Long form of member must have a value member 'type'
|
||||||
|
{ 'enum': 'TestEnum',
|
||||||
|
'data': [ 'integer', 's8' ] }
|
||||||
{ 'union': 'UnionInvalidBranch',
|
{ 'union': 'UnionInvalidBranch',
|
||||||
|
'base': { 'type': 'TestEnum' },
|
||||||
|
'discriminator': 'type',
|
||||||
'data': { 'integer': { 'if': 'foo'},
|
'data': { 'integer': { 'if': 'foo'},
|
||||||
's8': 'int8' } }
|
's8': 'int8' } }
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
union-clash-branches.json: In union 'TestUnion':
|
|
||||||
union-clash-branches.json:6: name of 'data' member 'a_b' must not use uppercase or '_'
|
|
|
@ -1,7 +0,0 @@
|
||||||
# Union branch name collision
|
|
||||||
# Naming rules make collision impossible (even with the pragma). If
|
|
||||||
# that wasn't the case, then we'd get collisions in generated C: two
|
|
||||||
# union members a_b, and two enum members TEST_UNION_A_B.
|
|
||||||
{ 'pragma': { 'member-name-exceptions': [ 'TestUnion' ] } }
|
|
||||||
{ 'union': 'TestUnion',
|
|
||||||
'data': { 'a-b': 'int', 'a_b': 'str' } }
|
|
2
tests/qapi-schema/union-clash-member.err
Normal file
2
tests/qapi-schema/union-clash-member.err
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
union-clash-member.json: In union 'TestUnion':
|
||||||
|
union-clash-member.json:11: member 'name' of type 'Branch1' collides with member 'name' of type 'Base'
|
2
tests/qapi-schema/union-discriminator-bad-name.err
Normal file
2
tests/qapi-schema/union-discriminator-bad-name.err
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
union-discriminator-bad-name.json: In union 'MyUnion':
|
||||||
|
union-discriminator-bad-name.json:6: discriminator '*switch' is not a member of 'base'
|
|
@ -1,2 +1,2 @@
|
||||||
union-empty.json: In union 'Union':
|
union-empty.json: In union 'Union':
|
||||||
union-empty.json:2: union has no branches
|
union-empty.json:4: union has no branches
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
# simple unions cannot be empty
|
# union discriminator enum cannot be empty
|
||||||
{ 'union': 'Union', 'data': { } }
|
{ 'enum': 'Empty', 'data': [ ] }
|
||||||
|
{ 'struct': 'Base', 'data': { 'type': 'Empty' } }
|
||||||
|
{ 'union': 'Union', 'base': 'Base', 'discriminator': 'type', 'data': { } }
|
||||||
|
|
2
tests/qapi-schema/union-inline-invalid-dict.err
Normal file
2
tests/qapi-schema/union-inline-invalid-dict.err
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
union-inline-invalid-dict.json: In union 'TestUnion':
|
||||||
|
union-inline-invalid-dict.json:7: 'data' member 'value1' misses key 'type'
|
2
tests/qapi-schema/union-int-branch.err
Normal file
2
tests/qapi-schema/union-int-branch.err
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
union-int-branch.json: In union 'TestUnion':
|
||||||
|
union-int-branch.json:8: branch 'value1' cannot use built-in type 'int'
|
|
@ -1,4 +1,4 @@
|
||||||
# we require flat union branches to be a struct
|
# we require union branches to be a struct
|
||||||
{ 'enum': 'TestEnum',
|
{ 'enum': 'TestEnum',
|
||||||
'data': [ 'value1', 'value2' ] }
|
'data': [ 'value1', 'value2' ] }
|
||||||
{ 'struct': 'Base',
|
{ 'struct': 'Base',
|
2
tests/qapi-schema/union-invalid-branch-key.err
Normal file
2
tests/qapi-schema/union-invalid-branch-key.err
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
union-invalid-branch-key.json: In union 'TestUnion':
|
||||||
|
union-invalid-branch-key.json:13: branch 'value_wrong' is not a value of enum type 'TestEnum'
|
2
tests/qapi-schema/union-invalid-discriminator.err
Normal file
2
tests/qapi-schema/union-invalid-discriminator.err
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
union-invalid-discriminator.json: In union 'TestUnion':
|
||||||
|
union-invalid-discriminator.json:10: discriminator 'enum_wrong' is not a member of 'base'
|
2
tests/qapi-schema/union-invalid-if-discriminator.err
Normal file
2
tests/qapi-schema/union-invalid-if-discriminator.err
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
union-invalid-if-discriminator.json: In union 'TestUnion':
|
||||||
|
union-invalid-if-discriminator.json:10: discriminator member 'enum1' of 'base' must not be conditional
|
2
tests/qapi-schema/union-no-base.err
Normal file
2
tests/qapi-schema/union-no-base.err
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
union-no-base.json: In union 'TestUnion':
|
||||||
|
union-no-base.json:8: union misses key 'base'
|
|
@ -1,4 +1,4 @@
|
||||||
# flat unions require a base
|
# unions require a base
|
||||||
{ 'struct': 'TestTypeA',
|
{ 'struct': 'TestTypeA',
|
||||||
'data': { 'string': 'str' } }
|
'data': { 'string': 'str' } }
|
||||||
{ 'struct': 'TestTypeB',
|
{ 'struct': 'TestTypeB',
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue