mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-11-05 20:35:44 +00: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);
|
||||
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);
|
||||
|
||||
return options;
|
||||
|
|
|
@ -321,7 +321,7 @@ static TpmTypeOptions *tpm_passthrough_get_tpm_options(TPMBackend *tb)
|
|||
{
|
||||
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,
|
||||
TPM_PASSTHROUGH(tb)->options);
|
||||
|
||||
|
|
|
@ -1520,7 +1520,7 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
|
|||
addr = g_new0(SocketAddressLegacy, 1);
|
||||
if (path) {
|
||||
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->path = g_strdup(path);
|
||||
#ifdef CONFIG_LINUX
|
||||
|
@ -1530,7 +1530,7 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
|
|||
q_unix->abstract = abstract;
|
||||
#endif
|
||||
} 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 = (InetSocketAddress) {
|
||||
.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),
|
||||
};
|
||||
} 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->str = g_strdup(fd);
|
||||
} else {
|
||||
|
|
|
@ -165,7 +165,7 @@ static void qemu_chr_parse_udp(QemuOpts *opts, ChardevBackend *backend,
|
|||
qemu_chr_parse_common(opts, qapi_ChardevUdp_base(udp));
|
||||
|
||||
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 = (InetSocketAddress) {
|
||||
.host = g_strdup(host),
|
||||
|
@ -180,7 +180,7 @@ static void qemu_chr_parse_udp(QemuOpts *opts, ChardevBackend *backend,
|
|||
if (has_local) {
|
||||
udp->has_local = true;
|
||||
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 = (InetSocketAddress) {
|
||||
.host = g_strdup(localaddr),
|
||||
|
|
|
@ -319,13 +319,9 @@ Union types
|
|||
Syntax::
|
||||
|
||||
UNION = { 'union': STRING,
|
||||
'data': BRANCHES,
|
||||
'*if': COND,
|
||||
'*features': FEATURES }
|
||||
| { 'union': STRING,
|
||||
'data': BRANCHES,
|
||||
'base': ( MEMBERS | STRING ),
|
||||
'discriminator': STRING,
|
||||
'data': BRANCHES,
|
||||
'*if': COND,
|
||||
'*features': FEATURES }
|
||||
BRANCHES = { BRANCH, ... }
|
||||
|
@ -334,63 +330,30 @@ Syntax::
|
|||
|
||||
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_
|
||||
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
|
||||
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
|
||||
with the common members (from the base type) and the selected branch's
|
||||
members. The two sets of member names must be disjoint. Member
|
||||
'discriminator' must name a non-optional enum-typed member of the base
|
||||
struct.
|
||||
Each BRANCH of the 'data' object defines a branch of the union. A
|
||||
union must have at least one branch.
|
||||
|
||||
The following example enhances the above simple union example by
|
||||
adding an optional common member 'read-only', renaming the
|
||||
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 STRING name is the branch name. It must be a value of
|
||||
the discriminator enum type.
|
||||
|
||||
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' ] }
|
||||
{ 'union': 'BlockdevOptions',
|
||||
|
@ -406,30 +369,11 @@ Resulting in these JSON objects::
|
|||
{ "driver": "qcow2", "read-only": false,
|
||||
"backing": "/some/place/my-image", "lazy-refcounts": true }
|
||||
|
||||
Notice that in a flat union, the discriminator name is controlled by
|
||||
the user, but because it must map to a base member with enum type, the
|
||||
code generator ensures that branches match the existing values of the
|
||||
enum. The order of branches need not match the order of the enum
|
||||
values. The branches need not cover all possible enum values.
|
||||
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 order of branches need not match the order of the enum values.
|
||||
The branches need not cover all possible enum values. In the
|
||||
resulting generated C data types, a 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.
|
||||
|
||||
The optional 'if' member specifies a conditional. See `Configuring
|
||||
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
|
||||
member 'bar' ::
|
||||
|
||||
{ 'struct': 'IfStruct', 'data':
|
||||
{ 'foo': 'int',
|
||||
'bar': { 'type': 'int', 'if': 'IFCOND'} } }
|
||||
{ 'struct': 'IfStruct',
|
||||
'data': { 'foo': 'int',
|
||||
'bar': { 'type': 'int', 'if': 'IFCOND'} } }
|
||||
|
||||
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
|
||||
value 'bar' ::
|
||||
|
||||
{ 'enum': 'IfEnum', 'data':
|
||||
[ 'foo',
|
||||
{ 'name' : 'bar', 'if': 'IFCOND' } ] }
|
||||
{ 'enum': 'IfEnum',
|
||||
'data': [ 'foo',
|
||||
{ 'name' : 'bar', 'if': 'IFCOND' } ] }
|
||||
|
||||
Likewise, features can be conditional. This requires the longhand
|
||||
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
|
||||
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`_ ::
|
||||
|
||||
{ "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
|
||||
"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
|
||||
variant member "members". "members" is a JSON array. Each element is
|
||||
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));
|
||||
|
||||
monitor_printf(mon, " \\ %s: type=%s",
|
||||
ti->id, TpmTypeOptionsKind_str(ti->options->type));
|
||||
ti->id, TpmType_str(ti->options->type));
|
||||
|
||||
switch (ti->options->type) {
|
||||
case TPM_TYPE_OPTIONS_KIND_PASSTHROUGH:
|
||||
case TPM_TYPE_PASSTHROUGH:
|
||||
tpo = ti->options->u.passthrough.data;
|
||||
monitor_printf(mon, "%s%s%s%s",
|
||||
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 ? tpo->cancel_path : "");
|
||||
break;
|
||||
case TPM_TYPE_OPTIONS_KIND_EMULATOR:
|
||||
case TPM_TYPE_EMULATOR:
|
||||
teo = ti->options->u.emulator.data;
|
||||
monitor_printf(mon, ",chardev=%s", teo->chardev);
|
||||
break;
|
||||
case TPM_TYPE_OPTIONS_KIND__MAX:
|
||||
case TPM_TYPE__MAX:
|
||||
break;
|
||||
}
|
||||
monitor_printf(mon, "\n");
|
||||
|
|
|
@ -139,6 +139,52 @@
|
|||
'*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:
|
||||
#
|
||||
|
@ -147,14 +193,13 @@
|
|||
# Since: 1.7
|
||||
##
|
||||
{ 'union': 'ImageInfoSpecific',
|
||||
'base': { 'type': 'ImageInfoSpecificKind' },
|
||||
'discriminator': 'type',
|
||||
'data': {
|
||||
'qcow2': 'ImageInfoSpecificQCow2',
|
||||
'vmdk': 'ImageInfoSpecificVmdk',
|
||||
# If we need to add block driver specific parameters for
|
||||
# LUKS in future, then we'll subclass QCryptoBlockInfoLUKS
|
||||
# to define a ImageInfoSpecificLUKS
|
||||
'luks': 'QCryptoBlockInfoLUKS',
|
||||
'rbd': 'ImageInfoSpecificRbd'
|
||||
'qcow2': 'ImageInfoSpecificQCow2Wrapper',
|
||||
'vmdk': 'ImageInfoSpecificVmdkWrapper',
|
||||
'luks': 'ImageInfoSpecificLUKSWrapper',
|
||||
'rbd': 'ImageInfoSpecificRbdWrapper'
|
||||
} }
|
||||
|
||||
##
|
||||
|
|
190
qapi/char.json
190
qapi/char.json
|
@ -407,39 +407,185 @@
|
|||
'base': 'ChardevCommon',
|
||||
'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:
|
||||
#
|
||||
# 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',
|
||||
'data': { 'file': 'ChardevFile',
|
||||
'serial': 'ChardevHostdev',
|
||||
'parallel': 'ChardevHostdev',
|
||||
'pipe': 'ChardevHostdev',
|
||||
'socket': 'ChardevSocket',
|
||||
'udp': 'ChardevUdp',
|
||||
'pty': 'ChardevCommon',
|
||||
'null': 'ChardevCommon',
|
||||
'mux': 'ChardevMux',
|
||||
'msmouse': 'ChardevCommon',
|
||||
'wctablet': 'ChardevCommon',
|
||||
'braille': 'ChardevCommon',
|
||||
'testdev': 'ChardevCommon',
|
||||
'stdio': 'ChardevStdio',
|
||||
'console': 'ChardevCommon',
|
||||
'spicevmc': { 'type': 'ChardevSpiceChannel',
|
||||
'base': { 'type': 'ChardevBackendKind' },
|
||||
'discriminator': 'type',
|
||||
'data': { 'file': 'ChardevFileWrapper',
|
||||
'serial': 'ChardevHostdevWrapper',
|
||||
'parallel': 'ChardevHostdevWrapper',
|
||||
'pipe': 'ChardevHostdevWrapper',
|
||||
'socket': 'ChardevSocketWrapper',
|
||||
'udp': 'ChardevUdpWrapper',
|
||||
'pty': 'ChardevCommonWrapper',
|
||||
'null': 'ChardevCommonWrapper',
|
||||
'mux': 'ChardevMuxWrapper',
|
||||
'msmouse': 'ChardevCommonWrapper',
|
||||
'wctablet': 'ChardevCommonWrapper',
|
||||
'braille': 'ChardevCommonWrapper',
|
||||
'testdev': 'ChardevCommonWrapper',
|
||||
'stdio': 'ChardevStdioWrapper',
|
||||
'console': 'ChardevCommonWrapper',
|
||||
'spicevmc': { 'type': 'ChardevSpiceChannelWrapper',
|
||||
'if': 'CONFIG_SPICE' },
|
||||
'spiceport': { 'type': 'ChardevSpicePort',
|
||||
'spiceport': { 'type': 'ChardevSpicePortWrapper',
|
||||
'if': 'CONFIG_SPICE' },
|
||||
'qemu-vdagent': { 'type': 'ChardevQemuVDAgent',
|
||||
'qemu-vdagent': { 'type': 'ChardevQemuVDAgentWrapper',
|
||||
'if': 'CONFIG_SPICE_PROTOCOL' },
|
||||
'vc': 'ChardevVC',
|
||||
'ringbuf': 'ChardevRingbuf',
|
||||
'vc': 'ChardevVCWrapper',
|
||||
'ringbuf': 'ChardevRingbufWrapper',
|
||||
# next one is just for compatibility
|
||||
'memory': 'ChardevRingbuf' } }
|
||||
'memory': 'ChardevRingbufWrapper' } }
|
||||
|
||||
##
|
||||
# @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:
|
||||
#
|
||||
|
@ -1205,10 +1237,12 @@
|
|||
# Since: 2.1
|
||||
##
|
||||
{ 'union': 'MemoryDeviceInfo',
|
||||
'data': { 'dimm': 'PCDIMMDeviceInfo',
|
||||
'nvdimm': 'PCDIMMDeviceInfo',
|
||||
'virtio-pmem': 'VirtioPMEMDeviceInfo',
|
||||
'virtio-mem': 'VirtioMEMDeviceInfo'
|
||||
'base': { 'type': 'MemoryDeviceInfoKind' },
|
||||
'discriminator': 'type',
|
||||
'data': { 'dimm': 'PCDIMMDeviceInfoWrapper',
|
||||
'nvdimm': 'PCDIMMDeviceInfoWrapper',
|
||||
'virtio-pmem': 'VirtioPMEMDeviceInfoWrapper',
|
||||
'virtio-mem': 'VirtioMEMDeviceInfoWrapper'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -110,6 +110,38 @@
|
|||
'cid': '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:
|
||||
#
|
||||
|
@ -117,18 +149,18 @@
|
|||
#
|
||||
# Note: This type is deprecated in favor of SocketAddress. The
|
||||
# difference between SocketAddressLegacy and SocketAddress is that the
|
||||
# latter is a flat union rather than a simple union. Flat is nicer
|
||||
# because it avoids nesting on the wire, i.e. that form has fewer {}.
|
||||
|
||||
# latter is has fewer {} on the wire.
|
||||
#
|
||||
# Since: 1.3
|
||||
##
|
||||
{ 'union': 'SocketAddressLegacy',
|
||||
'base': { 'type': 'SocketAddressType' },
|
||||
'discriminator': 'type',
|
||||
'data': {
|
||||
'inet': 'InetSocketAddress',
|
||||
'unix': 'UnixSocketAddress',
|
||||
'vsock': 'VsockSocketAddress',
|
||||
'fd': 'String' } }
|
||||
'inet': 'InetSocketAddressWrapper',
|
||||
'unix': 'UnixSocketAddressWrapper',
|
||||
'vsock': 'VsockSocketAddressWrapper',
|
||||
'fd': 'StringWrapper' } }
|
||||
|
||||
##
|
||||
# @SocketAddressType:
|
||||
|
|
|
@ -99,6 +99,24 @@
|
|||
{ 'struct': 'TPMEmulatorOptions', 'data': { 'chardev' : 'str' },
|
||||
'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:
|
||||
#
|
||||
|
@ -110,8 +128,10 @@
|
|||
# Since: 1.5
|
||||
##
|
||||
{ 'union': 'TpmTypeOptions',
|
||||
'data': { 'passthrough' : 'TPMPassthroughOptions',
|
||||
'emulator': 'TPMEmulatorOptions' },
|
||||
'base': { 'type': 'TpmType' },
|
||||
'discriminator': 'type',
|
||||
'data': { 'passthrough' : 'TPMPassthroughOptionsWrapper',
|
||||
'emulator': 'TPMEmulatorOptionsWrapper' },
|
||||
'if': 'CONFIG_TPM' }
|
||||
|
||||
##
|
||||
|
|
|
@ -38,41 +38,128 @@
|
|||
{ 'enum': 'ActionCompletionMode',
|
||||
'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:
|
||||
#
|
||||
# A discriminated record of operations that can be performed with
|
||||
# @transaction. Action @type can be:
|
||||
#
|
||||
# - @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
|
||||
# @transaction.
|
||||
#
|
||||
# Since: 1.1
|
||||
##
|
||||
{ 'union': 'TransactionAction',
|
||||
'base': { 'type': 'TransactionActionKind' },
|
||||
'discriminator': 'type',
|
||||
'data': {
|
||||
'abort': 'Abort',
|
||||
'block-dirty-bitmap-add': 'BlockDirtyBitmapAdd',
|
||||
'block-dirty-bitmap-remove': 'BlockDirtyBitmap',
|
||||
'block-dirty-bitmap-clear': 'BlockDirtyBitmap',
|
||||
'block-dirty-bitmap-enable': 'BlockDirtyBitmap',
|
||||
'block-dirty-bitmap-disable': 'BlockDirtyBitmap',
|
||||
'block-dirty-bitmap-merge': 'BlockDirtyBitmapMerge',
|
||||
'blockdev-backup': 'BlockdevBackup',
|
||||
'blockdev-snapshot': 'BlockdevSnapshot',
|
||||
'blockdev-snapshot-internal-sync': 'BlockdevSnapshotInternal',
|
||||
'blockdev-snapshot-sync': 'BlockdevSnapshotSync',
|
||||
'drive-backup': 'DriveBackup'
|
||||
'abort': 'AbortWrapper',
|
||||
'block-dirty-bitmap-add': 'BlockDirtyBitmapAddWrapper',
|
||||
'block-dirty-bitmap-remove': 'BlockDirtyBitmapWrapper',
|
||||
'block-dirty-bitmap-clear': 'BlockDirtyBitmapWrapper',
|
||||
'block-dirty-bitmap-enable': 'BlockDirtyBitmapWrapper',
|
||||
'block-dirty-bitmap-disable': 'BlockDirtyBitmapWrapper',
|
||||
'block-dirty-bitmap-merge': 'BlockDirtyBitmapMergeWrapper',
|
||||
'blockdev-backup': 'BlockdevBackupWrapper',
|
||||
'blockdev-snapshot': 'BlockdevSnapshotWrapper',
|
||||
'blockdev-snapshot-internal-sync': 'BlockdevSnapshotInternalWrapper',
|
||||
'blockdev-snapshot-sync': 'BlockdevSnapshotSyncWrapper',
|
||||
'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',
|
||||
'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:
|
||||
#
|
||||
|
@ -832,9 +856,11 @@
|
|||
# Since: 1.3
|
||||
##
|
||||
{ 'union': 'KeyValue',
|
||||
'base': { 'type': 'KeyValueKind' },
|
||||
'discriminator': 'type',
|
||||
'data': {
|
||||
'number': 'int',
|
||||
'qcode': 'QKeyCode' } }
|
||||
'number': 'IntWrapper',
|
||||
'qcode': 'QKeyCodeWrapper' } }
|
||||
|
||||
##
|
||||
# @send-key:
|
||||
|
@ -934,6 +960,38 @@
|
|||
'data' : { 'axis' : 'InputAxis',
|
||||
'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:
|
||||
#
|
||||
|
@ -949,10 +1007,12 @@
|
|||
# Since: 2.0
|
||||
##
|
||||
{ 'union' : 'InputEvent',
|
||||
'data' : { 'key' : 'InputKeyEvent',
|
||||
'btn' : 'InputBtnEvent',
|
||||
'rel' : 'InputMoveEvent',
|
||||
'abs' : 'InputMoveEvent' } }
|
||||
'base': { 'type': 'InputEventKind' },
|
||||
'discriminator': 'type',
|
||||
'data' : { 'key' : 'InputKeyEventWrapper',
|
||||
'btn' : 'InputBtnEventWrapper',
|
||||
'rel' : 'InputMoveEventWrapper',
|
||||
'abs' : 'InputMoveEventWrapper' } }
|
||||
|
||||
##
|
||||
# @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()`.
|
||||
- 'command' names adhere to `check_name_lower()`.
|
||||
- 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 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)
|
||||
else:
|
||||
check_name_camel(name, info, meta)
|
||||
if name.endswith('Kind') or name.endswith('List'):
|
||||
if name.endswith('List'):
|
||||
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,
|
||||
|
@ -513,27 +513,18 @@ def check_union(expr: _JSONObject, info: QAPISourceInfo) -> None:
|
|||
:return: None, ``expr`` is normalized in-place as needed.
|
||||
"""
|
||||
name = cast(str, expr['union']) # Checked in check_exprs
|
||||
base = expr.get('base')
|
||||
discriminator = expr.get('discriminator')
|
||||
base = expr['base']
|
||||
discriminator = expr['discriminator']
|
||||
members = expr['data']
|
||||
|
||||
if discriminator is None: # simple union
|
||||
if base is not None:
|
||||
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'")
|
||||
check_type(base, info, "'base'", allow_dict=name)
|
||||
check_name_is_str(discriminator, info, "'discriminator'")
|
||||
|
||||
if not isinstance(members, dict):
|
||||
raise QAPISemError(info, "'data' must be an object")
|
||||
|
||||
for (key, value) in members.items():
|
||||
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_if(value, info, source)
|
||||
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)
|
||||
elif meta == 'union':
|
||||
check_keys(expr, info, meta,
|
||||
['union', 'data'],
|
||||
['base', 'discriminator', 'if', 'features'])
|
||||
['union', 'base', 'discriminator', 'data'],
|
||||
['if', 'features'])
|
||||
normalize_members(expr.get('base'))
|
||||
normalize_members(expr['data'])
|
||||
check_union(expr, info)
|
||||
|
|
|
@ -321,8 +321,8 @@ def connect_doc(self, doc=None):
|
|||
m.connect_doc(doc)
|
||||
|
||||
def is_implicit(self):
|
||||
# See QAPISchema._make_implicit_enum_type() and ._def_predefineds()
|
||||
return self.name.endswith('Kind') or self.name == 'QType'
|
||||
# See QAPISchema._def_predefineds()
|
||||
return self.name == 'QType'
|
||||
|
||||
def c_type(self):
|
||||
return c_name(self.name)
|
||||
|
@ -393,8 +393,7 @@ class QAPISchemaObjectType(QAPISchemaType):
|
|||
def __init__(self, name, info, doc, ifcond, features,
|
||||
base, local_members, variants):
|
||||
# struct has local_members, optional base, and no variants
|
||||
# flat union has base, variants, and no local_members
|
||||
# simple union has local_members, variants, and no base
|
||||
# union has base, variants, and no local_members
|
||||
super().__init__(name, info, doc, ifcond, features)
|
||||
self.meta = 'union' if variants else 'struct'
|
||||
assert base is None or isinstance(base, str)
|
||||
|
@ -465,15 +464,6 @@ def connect_doc(self, doc=None):
|
|||
for m in self.local_members:
|
||||
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):
|
||||
# See QAPISchema._make_implicit_object_type(), as well as
|
||||
# _def_predefineds()
|
||||
|
@ -576,10 +566,9 @@ def visit(self, visitor):
|
|||
|
||||
class QAPISchemaVariants:
|
||||
def __init__(self, tag_name, info, tag_member, variants):
|
||||
# Flat unions pass tag_name but not tag_member.
|
||||
# Simple unions and alternates pass tag_member but not tag_name.
|
||||
# After check(), tag_member is always set, and tag_name remains
|
||||
# a reliable witness of being used by a flat union.
|
||||
# Unions pass tag_name but not tag_member.
|
||||
# Alternates pass tag_member but not tag_name.
|
||||
# After check(), tag_member is always set.
|
||||
assert bool(tag_member) != bool(tag_name)
|
||||
assert (isinstance(tag_name, str) or
|
||||
isinstance(tag_member, QAPISchemaObjectTypeMember))
|
||||
|
@ -595,7 +584,7 @@ def set_defined_in(self, name):
|
|||
v.set_defined_in(name)
|
||||
|
||||
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))
|
||||
base = "'base'"
|
||||
# Pointing to the base type when not implicit would be
|
||||
|
@ -625,11 +614,11 @@ def check(self, schema, seen):
|
|||
self.info,
|
||||
"discriminator member '%s' of %s must not be conditional"
|
||||
% (self._tag_name, base))
|
||||
else: # simple union
|
||||
else: # alternate
|
||||
assert isinstance(self.tag_member.type, QAPISchemaEnumType)
|
||||
assert not self.tag_member.optional
|
||||
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
|
||||
cases = {v.name for v in self.variants}
|
||||
for m in self.tag_member.type.members:
|
||||
|
@ -707,18 +696,10 @@ def describe(self, info):
|
|||
assert role == 'member'
|
||||
role = 'parameter'
|
||||
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
|
||||
else:
|
||||
# Implicit type created for a simple union's branch
|
||||
assert defined_in.endswith('-wrapper')
|
||||
# Unreachable and not implemented
|
||||
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:
|
||||
return "%s '%s' of type '%s'" % (role, self.name, defined_in)
|
||||
return "%s '%s'" % (role, self.name)
|
||||
|
@ -1004,15 +985,6 @@ def _make_enum_members(self, values, info):
|
|||
QAPISchemaIfCond(v.get('if')))
|
||||
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):
|
||||
name = element_type + 'List' # reserved by check_defn_name_str()
|
||||
if not self.lookup_type(name):
|
||||
|
@ -1026,17 +998,9 @@ def _make_implicit_object_type(self, name, info, ifcond, role, members):
|
|||
name = 'q_obj_%s-%s' % (name, role)
|
||||
typ = self.lookup_entity(name, QAPISchemaObjectType)
|
||||
if typ:
|
||||
# The implicit object type has multiple users. This is
|
||||
# either a duplicate definition (which will be flagged
|
||||
# later), or an implicit wrapper type used for multiple
|
||||
# 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
|
||||
# The implicit object type has multiple users. This can
|
||||
# only be a duplicate definition, which will be flagged
|
||||
# later.
|
||||
pass
|
||||
else:
|
||||
self._def_entity(QAPISchemaObjectType(
|
||||
|
@ -1084,49 +1048,28 @@ def _def_struct_type(self, expr, info, doc):
|
|||
def _make_variant(self, case, typ, ifcond, info):
|
||||
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):
|
||||
name = expr['union']
|
||||
base = expr['base']
|
||||
tag_name = expr['discriminator']
|
||||
data = expr['data']
|
||||
base = expr.get('base')
|
||||
ifcond = QAPISchemaIfCond(expr.get('if'))
|
||||
features = self._make_features(expr.get('features'), info)
|
||||
tag_name = expr.get('discriminator')
|
||||
tag_member = None
|
||||
if isinstance(base, dict):
|
||||
base = self._make_implicit_object_type(
|
||||
name, info, ifcond,
|
||||
'base', self._make_members(base, info))
|
||||
if tag_name:
|
||||
variants = [
|
||||
self._make_variant(key, value['type'],
|
||||
QAPISchemaIfCond(value.get('if')),
|
||||
info)
|
||||
for (key, value) in data.items()]
|
||||
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]
|
||||
variants = [
|
||||
self._make_variant(key, value['type'],
|
||||
QAPISchemaIfCond(value.get('if')),
|
||||
info)
|
||||
for (key, value) in data.items()]
|
||||
members = []
|
||||
self._def_entity(
|
||||
QAPISchemaObjectType(name, info, doc, ifcond, features,
|
||||
base, members,
|
||||
QAPISchemaVariants(
|
||||
tag_name, info, tag_member, variants)))
|
||||
tag_name, info, None, variants)))
|
||||
|
||||
def _def_alternate_type(self, expr, info, doc):
|
||||
name = expr['alternate']
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
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
|
||||
{ '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' }
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
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
|
||||
{ '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' } }
|
||||
|
|
|
@ -60,8 +60,8 @@
|
|||
#
|
||||
# @two is undocumented
|
||||
##
|
||||
{ 'enum': 'Enum', 'data':
|
||||
[ { 'name': 'one', 'if': 'IFONE' }, 'two' ],
|
||||
{ 'enum': 'Enum',
|
||||
'data': [ { 'name': 'one', 'if': 'IFONE' }, 'two' ],
|
||||
'features': [ 'enum-feat' ],
|
||||
'if': 'IFCOND' }
|
||||
|
||||
|
@ -107,15 +107,6 @@
|
|||
'two': { 'type': 'Variant2',
|
||||
'if': { 'any': ['IFONE', 'IFTWO'] } } } }
|
||||
|
||||
##
|
||||
# @SugaredUnion:
|
||||
# Features:
|
||||
# @union-feat2: a feature
|
||||
##
|
||||
{ 'union': 'SugaredUnion',
|
||||
'features': [ 'union-feat2' ],
|
||||
'data': { 'one': 'Variant1', 'two': { 'type': 'Variant2', 'if': 'IFTWO' } } }
|
||||
|
||||
##
|
||||
# @Alternate:
|
||||
# @i: an integer
|
||||
|
|
|
@ -32,21 +32,6 @@ object Object
|
|||
case two: Variant2
|
||||
if {'any': ['IFONE', 'IFTWO']}
|
||||
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
|
||||
tag type
|
||||
case i: int
|
||||
|
@ -149,13 +134,6 @@ doc symbol=Object
|
|||
|
||||
feature=union-feat1
|
||||
a feature
|
||||
doc symbol=SugaredUnion
|
||||
body=
|
||||
|
||||
arg=type
|
||||
|
||||
feature=union-feat2
|
||||
a feature
|
||||
doc symbol=Alternate
|
||||
body=
|
||||
|
||||
|
|
|
@ -130,26 +130,6 @@ Features
|
|||
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)
|
||||
-----------------------
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
# check invalid 'if' type
|
||||
{ 'enum': 'TestIfEnum', 'data':
|
||||
[ 'foo', { 'name' : 'bar', 'if': { 'val': 'foo' } } ] }
|
||||
{ 'enum': 'TestIfEnum',
|
||||
'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-no-list.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-word.json',
|
||||
'ident-with-escape.json',
|
||||
|
@ -168,7 +152,6 @@ schemas = [
|
|||
'reserved-member-q.json',
|
||||
'reserved-member-u.json',
|
||||
'reserved-member-underscore.json',
|
||||
'reserved-type-kind.json',
|
||||
'reserved-type-list.json',
|
||||
'returns-alternate.json',
|
||||
'returns-array-bad.json',
|
||||
|
@ -191,16 +174,28 @@ schemas = [
|
|||
'unclosed-list.json',
|
||||
'unclosed-object.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-no-discriminator.json',
|
||||
'union-branch-case.json',
|
||||
'union-base-union.json',
|
||||
'union-branch-if-invalid.json',
|
||||
'union-branch-invalid-dict.json',
|
||||
'union-clash-branches.json',
|
||||
'union-clash-member.json',
|
||||
'union-discriminator-bad-name.json',
|
||||
'union-empty.json',
|
||||
'union-inline-invalid-dict.json',
|
||||
'union-int-branch.json',
|
||||
'union-invalid-base.json',
|
||||
'union-invalid-branch-key.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',
|
||||
'unknown-escape.json',
|
||||
'unknown-expr-key.json',
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
{ 'struct': 'Empty1', 'data': { } }
|
||||
{ 'struct': 'Empty2', 'base': 'Empty1', 'data': { } }
|
||||
|
||||
# Likewise for an empty flat union
|
||||
# Likewise for an empty union
|
||||
{ 'union': 'Union',
|
||||
'base': { 'type': 'EnumOne' }, 'discriminator': 'type',
|
||||
'data': { } }
|
||||
|
@ -123,8 +123,7 @@
|
|||
# for testing use of 'str' within alternates
|
||||
{ 'alternate': 'AltStrObj', 'data': { 's': 'str', 'o': 'TestStruct' } }
|
||||
|
||||
# for testing lists
|
||||
{ 'union': 'UserDefListUnion',
|
||||
{ 'struct': 'ArrayStruct',
|
||||
'data': { 'integer': ['int'],
|
||||
's8': ['int8'],
|
||||
's16': ['int16'],
|
||||
|
@ -137,9 +136,9 @@
|
|||
'number': ['number'],
|
||||
'boolean': ['bool'],
|
||||
'string': ['str'],
|
||||
'sizes': ['size'],
|
||||
'any': ['any'],
|
||||
'user': ['Status'] } } # intentional forward ref. to sub-module
|
||||
'*sz': ['size'],
|
||||
'*any': ['any'],
|
||||
'*user': ['Status'] } } # intentional forward ref. to sub-module
|
||||
|
||||
# for testing sub-modules
|
||||
{ 'include': 'include/sub-module.json' }
|
||||
|
@ -159,7 +158,7 @@
|
|||
'returns': 'int' }
|
||||
{ 'command': 'guest-sync', 'data': { 'arg': 'any' }, 'returns': 'any' }
|
||||
{ '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' }
|
||||
|
||||
# Smoke test on out-of-band and allow-preconfig-test
|
||||
|
@ -203,11 +202,10 @@
|
|||
'data': { '__org.qemu_x-member1': '__org.qemu_x-Enum' } }
|
||||
{ 'struct': '__org.qemu_x-Struct', 'base': '__org.qemu_x-Base',
|
||||
'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' } }
|
||||
{ 'struct': '__org.qemu_x-Struct2',
|
||||
'data': { 'array': ['__org.qemu_x-Union1'] } }
|
||||
{ 'union': '__org.qemu_x-Union2', 'base': '__org.qemu_x-Base',
|
||||
'data': { 'array': ['__org.qemu_x-Union'] } }
|
||||
{ 'union': '__org.qemu_x-Union', 'base': '__org.qemu_x-Base',
|
||||
'discriminator': '__org.qemu_x-member1',
|
||||
'data': { '__org.qemu_x-value': '__org.qemu_x-Struct2' } }
|
||||
{ 'alternate': '__org.qemu_x-Alt',
|
||||
|
@ -215,32 +213,33 @@
|
|||
{ 'event': '__ORG.QEMU_X-EVENT', 'data': '__org.qemu_x-Struct' }
|
||||
{ 'command': '__org.qemu_x-command',
|
||||
'data': { 'a': ['__org.qemu_x-Enum'], 'b': ['__org.qemu_x-Struct'],
|
||||
'c': '__org.qemu_x-Union2', 'd': '__org.qemu_x-Alt' },
|
||||
'returns': '__org.qemu_x-Union1' }
|
||||
'c': '__org.qemu_x-Union', 'd': '__org.qemu_x-Alt' } }
|
||||
|
||||
# test 'if' condition handling
|
||||
|
||||
{ 'struct': 'TestIfStruct', 'data':
|
||||
{ 'foo': 'int',
|
||||
'bar': { 'type': 'int', 'if': 'TEST_IF_STRUCT_BAR'} },
|
||||
{ 'struct': 'TestIfStruct',
|
||||
'data': { 'foo': 'int',
|
||||
'bar': { 'type': 'int', 'if': 'TEST_IF_STRUCT_BAR'} },
|
||||
'if': 'TEST_IF_STRUCT' }
|
||||
|
||||
{ 'enum': 'TestIfEnum', 'data':
|
||||
[ 'foo', { 'name' : 'bar', 'if': 'TEST_IF_ENUM_BAR' } ],
|
||||
{ 'enum': 'TestIfEnum',
|
||||
'data': [ 'foo', { 'name' : 'bar', 'if': 'TEST_IF_ENUM_BAR' } ],
|
||||
'if': 'TEST_IF_ENUM' }
|
||||
|
||||
{ 'union': 'TestIfUnion', 'data':
|
||||
{ 'foo': 'TestStruct',
|
||||
'bar': { 'type': 'str', 'if': 'TEST_IF_UNION_BAR'} },
|
||||
{ 'union': 'TestIfUnion',
|
||||
'base': { 'type': 'TestIfEnum' },
|
||||
'discriminator': 'type',
|
||||
'data': { 'foo': 'TestStruct',
|
||||
'bar': { 'type': 'UserDefZero', 'if': 'TEST_IF_ENUM_BAR'} },
|
||||
'if': { 'all': ['TEST_IF_UNION', 'TEST_IF_STRUCT'] } }
|
||||
|
||||
{ 'command': 'test-if-union-cmd',
|
||||
'data': { 'union-cmd-arg': 'TestIfUnion' },
|
||||
'if': { 'all': ['TEST_IF_UNION', 'TEST_IF_STRUCT'] } }
|
||||
|
||||
{ 'alternate': 'TestIfAlternate', 'data':
|
||||
{ 'foo': 'int',
|
||||
'bar': { 'type': 'TestStruct', 'if': 'TEST_IF_ALT_BAR'} },
|
||||
{ 'alternate': 'TestIfAlternate',
|
||||
'data': { 'foo': 'int',
|
||||
'bar': { 'type': 'TestStruct', 'if': 'TEST_IF_ALT_BAR'} },
|
||||
'if': { 'all': ['TEST_IF_ALT', 'TEST_IF_STRUCT'] } }
|
||||
|
||||
{ 'command': 'test-if-alternate-cmd',
|
||||
|
@ -256,9 +255,9 @@
|
|||
|
||||
{ 'command': 'test-cmd-return-def-three', 'returns': 'UserDefThree' }
|
||||
|
||||
{ 'event': 'TEST_IF_EVENT', 'data':
|
||||
{ 'foo': 'TestIfStruct',
|
||||
'bar': { 'type': ['TestIfEnum'], 'if': 'TEST_IF_EVT_BAR' } },
|
||||
{ 'event': 'TEST_IF_EVENT',
|
||||
'data': { 'foo': 'TestIfStruct',
|
||||
'bar': { 'type': ['TestIfEnum'], 'if': 'TEST_IF_EVT_BAR' } },
|
||||
'if': { 'all': ['TEST_IF_EVT', 'TEST_IF_STRUCT'] } }
|
||||
|
||||
{ 'event': 'TEST_IF_EVENT2', 'data': {},
|
||||
|
|
|
@ -125,70 +125,22 @@ alternate AltStrObj
|
|||
tag type
|
||||
case s: str
|
||||
case o: TestStruct
|
||||
object q_obj_intList-wrapper
|
||||
member data: intList optional=False
|
||||
object q_obj_int8List-wrapper
|
||||
member data: int8List optional=False
|
||||
object q_obj_int16List-wrapper
|
||||
member data: int16List optional=False
|
||||
object q_obj_int32List-wrapper
|
||||
member data: int32List optional=False
|
||||
object q_obj_int64List-wrapper
|
||||
member data: int64List optional=False
|
||||
object q_obj_uint8List-wrapper
|
||||
member data: uint8List optional=False
|
||||
object q_obj_uint16List-wrapper
|
||||
member data: uint16List optional=False
|
||||
object q_obj_uint32List-wrapper
|
||||
member data: uint32List optional=False
|
||||
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
|
||||
object ArrayStruct
|
||||
member integer: intList optional=False
|
||||
member s8: int8List optional=False
|
||||
member s16: int16List optional=False
|
||||
member s32: int32List optional=False
|
||||
member s64: int64List optional=False
|
||||
member u8: uint8List optional=False
|
||||
member u16: uint16List optional=False
|
||||
member u32: uint32List optional=False
|
||||
member u64: uint64List optional=False
|
||||
member number: numberList optional=False
|
||||
member boolean: boolList optional=False
|
||||
member string: strList optional=False
|
||||
member sz: sizeList optional=True
|
||||
member any: anyList optional=True
|
||||
member user: StatusList optional=True
|
||||
include include/sub-module.json
|
||||
command user-def-cmd None -> None
|
||||
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
|
||||
command boxed-struct UserDefZero -> None
|
||||
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
|
||||
command boxed-empty Empty1 -> None
|
||||
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
|
||||
member __org.qemu_x-member2: str optional=False
|
||||
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
|
||||
tag type
|
||||
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
|
||||
member array: __org.qemu_x-Union1List optional=False
|
||||
object __org.qemu_x-Union2
|
||||
member array: __org.qemu_x-UnionList optional=False
|
||||
object __org.qemu_x-Union
|
||||
base __org.qemu_x-Base
|
||||
tag __org.qemu_x-member1
|
||||
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
|
||||
member a: __org.qemu_x-EnumList 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
|
||||
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
|
||||
object TestIfStruct
|
||||
member foo: int optional=False
|
||||
|
@ -305,19 +249,15 @@ enum TestIfEnum
|
|||
member bar
|
||||
if TEST_IF_ENUM_BAR
|
||||
if TEST_IF_ENUM
|
||||
object q_obj_TestStruct-wrapper
|
||||
member data: TestStruct optional=False
|
||||
enum TestIfUnionKind
|
||||
member foo
|
||||
member bar
|
||||
if TEST_IF_UNION_BAR
|
||||
object q_obj_TestIfUnion-base
|
||||
member type: TestIfEnum optional=False
|
||||
if {'all': ['TEST_IF_UNION', 'TEST_IF_STRUCT']}
|
||||
object TestIfUnion
|
||||
member type: TestIfUnionKind optional=False
|
||||
base q_obj_TestIfUnion-base
|
||||
tag type
|
||||
case foo: q_obj_TestStruct-wrapper
|
||||
case bar: q_obj_str-wrapper
|
||||
if TEST_IF_UNION_BAR
|
||||
case foo: TestStruct
|
||||
case bar: UserDefZero
|
||||
if TEST_IF_ENUM_BAR
|
||||
if {'all': ['TEST_IF_UNION', 'TEST_IF_STRUCT']}
|
||||
object q_obj_test-if-union-cmd-arg
|
||||
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
|
||||
# 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
|
||||
# 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
|
||||
{ '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))
|
||||
|
||||
|
||||
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):
|
||||
sys.stdout = StringIO()
|
||||
try:
|
||||
|
@ -148,13 +159,12 @@ def test_and_diff(test_name, dir_name, update):
|
|||
sys.stdout.close()
|
||||
sys.stdout = sys.__stdout__
|
||||
|
||||
mode = 'r+' if update else 'r'
|
||||
try:
|
||||
outfp = open(os.path.join(dir_name, test_name + '.out'), mode)
|
||||
errfp = open(os.path.join(dir_name, test_name + '.err'), mode)
|
||||
outfp = open_test_result(dir_name, test_name + '.out', update)
|
||||
errfp = open_test_result(dir_name, test_name + '.err', update)
|
||||
expected_out = outfp.readlines()
|
||||
expected_err = errfp.readlines()
|
||||
except IOError as err:
|
||||
except OSError as err:
|
||||
print("%s: can't open '%s': %s"
|
||||
% (sys.argv[0], err.filename, err.strerror),
|
||||
file=sys.stderr)
|
||||
|
@ -180,7 +190,7 @@ def test_and_diff(test_name, dir_name, update):
|
|||
errfp.truncate(0)
|
||||
errfp.seek(0)
|
||||
errfp.writelines(actual_err)
|
||||
except IOError as err:
|
||||
except OSError as err:
|
||||
print("%s: can't write '%s': %s"
|
||||
% (sys.argv[0], err.filename, err.strerror),
|
||||
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',
|
||||
'data': [ 'value1', 'value2' ] }
|
||||
{ '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': { } }
|
||||
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
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',
|
||||
'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' } }
|
||||
{ 'struct': 'TestTypeB',
|
||||
'data': { 'integer': 'int' } }
|
||||
{ 'enum': 'Enum', 'data': [ 'kind1', 'kind2' ] }
|
||||
{ 'union': 'UnionBase',
|
||||
'base': { 'type': 'Enum' },
|
||||
'discriminator': 'type',
|
||||
'data': { 'kind1': 'TestTypeA',
|
||||
'kind2': 'TestTypeB' } }
|
||||
{ '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: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'
|
||||
{ 'enum': 'TestEnum',
|
||||
'data': [ 'integer', 's8' ] }
|
||||
{ 'union': 'UnionInvalidBranch',
|
||||
'base': { 'type': 'TestEnum' },
|
||||
'discriminator': 'type',
|
||||
'data': { 'integer': { 'if': 'foo'},
|
||||
'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:2: union has no branches
|
||||
union-empty.json:4: union has no branches
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
# simple unions cannot be empty
|
||||
{ 'union': 'Union', 'data': { } }
|
||||
# union discriminator enum cannot be empty
|
||||
{ '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',
|
||||
'data': [ 'value1', 'value2' ] }
|
||||
{ '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',
|
||||
'data': { 'string': 'str' } }
|
||||
{ 'struct': 'TestTypeB',
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue