Commit graph

175 commits

Author SHA1 Message Date
Eric Blake 97c801d6a1
qapi: Prefer typesafe upcasts to qapi base classes
A previous patch (commit 1e6c1616) made it possible to
directly cast from a qapi flat union type to its base type.
However, it requires the use of a C cast, which turns off
compiler type-safety checks. Fortunately, no such casts
exist, just yet.

Regardless, add inline type-safe wrappers named
qapi_FOO_base() for any union type FOO that has a base,
which can be used for a safer upcast, and enhance the
testsuite to cover the new functionality.

A future patch will extend the upcast support to structs,
where such conversions do exist already.

Note that C makes const-correct upcasts annoying because
it lacks overloads; these functions cast away const so that
they can accept user pointers whether const or not, and the
result in turn can be assigned to normal or const pointers.
Alternatively, this could have been done with macros, but
type-safe macros are hairy, and not worthwhile here.

This patch just adds upcasts. None of our code needed to
downcast from a base qapi class to a child. Also, in the
case of grandchildren (such as BlockdevOptionsQcow2), the
caller will need to call two functions to get to the inner
base (although it wouldn't be too hard to generate a
qapi_FOO_base_base() if desired). If a user changes qapi
to alter the base class hierarchy, such as going from
'A -> C' to 'A -> B -> C', it will change the type of
'qapi_C_base()', and the compiler will point out the places
that are affected by the new base.

One alternative was proposed, but was deemed too ugly to use
in practice: the generators could output redundant
information using anonymous types:
| struct Child {
| union {
| struct {
| Type1 parent_member1;
| Type2 parent_member2;
| };
| Parent base;
| };
| };
With that ugly proposal, for a given qapi type, obj->member
and obj->base.member would refer to the same storage; allowing
convenience in working with members without needing 'base.'
allowing typesafe upcast without needing a C cast by accessing
'&obj->base', and allowing downcasts from the parent back to
the child possible through container_of(obj, Child, base).

Backports commit 30594fe1cd4355626e73b80645428105d0df3cf6 from qemu
2018-02-19 19:14:03 -05:00
Eric Blake ac0ee0286c
qapi-types: Refactor base fields output
Move code from gen_union() into gen_struct_fields() in order for
a later patch to share code when enumerating inherited fields
for struct types.

No change to generated code.

Backports commit f87ab7f9bd956250c48b5c6e9b607b537fd21543 from qemu
2018-02-19 19:13:01 -05:00
Eric Blake 61e59c4c62
qapi-visit: Split off visit_type_FOO_fields forward decl
We generate a static visit_type_FOO_fields() for every type
FOO. However, sometimes we need a forward declaration. Split
the code to generate the forward declaration out of
gen_visit_implicit_struct() into a new gen_visit_fields_decl(),
and also prepare for a forward declaration to be emitted
during gen_visit_struct(), so that a future patch can switch
from using visit_type_FOO_implicit() to the simpler
visit_type_FOO_fields() as part of unboxing the base class
of a struct.

No change to generated code.

Backports commit d02cf37766ba3cf918d7085aa7848c9dc05fd11a from qemu
2018-02-19 19:11:33 -05:00
Eric Blake 1f11f92a80
qapi: Reserve 'q_*' and 'has_*' member names
c_name() produces names starting with 'q_' when protecting a
dictionary member name that would fail to directly compile, but
in doing so can cause clashes with any member name already
beginning with 'q-' or 'q_'. Likewise, we create a C name 'has_'
for any optional member that can clash with any member name
beginning with 'has-' or 'has_'.

Technically, rather than blindly reserving the namespace,
we could try to complain about user names only when an actual
collision occurs, or even teach c_name() how to munge names
to avoid collisions. But it is not trivial, especially when
collisions can occur across multiple types (such as via
inheritance or flat unions). Besides, no existing .json
files are trying to use these names. So it's easier to just
outright forbid the potential for collision. We can always
relax things in the future if a real need arises for QMP to
express member names that have been forbidden here.

'has_' only has to be reserved for struct/union member names,
while 'q_' is reserved everywhere (matching the fact that
only members can be optional, while we use c_name() for munging
both members and entities). Note that we could relax 'q_'
restrictions on entities independently from member names; for
example, c_name('qmp_' + 'unix') would result in a different
function name than our current 'qmp_' + c_name('unix').

Update and add tests to cover the new error messages.

Backports commit 9fb081e0b98409556d023c7193eeb68947cd1211 from qemu
2018-02-19 19:09:17 -05:00
Eric Blake b9f93dd0e8
qapi: Reserve '*List' type names for list types
Type names ending in 'List' can clash with qapi list types in
generated C. We don't currently use such names. It is easier to
outlaw them now than to worry about how to resolve such a clash
in the future. For precedence, see commit 4dc2e69, which did the
same for names ending in 'Kind' versus implicit enum types for
qapi unions.

Update the testsuite to match.

Backports commit 255960dd374d4497d6ea537305f1b0d8a3433789 from qemu
2018-02-19 19:08:12 -05:00
Eric Blake 017baefb66
qapi: More robust conditions for when labels are needed
We were using regular expressions to see if ret included
any earlier text that emitted a 'goto out;' line, to decide
whether we needed to output an 'out:' label. But this is
fragile, if the ret text can possibly combine more than one
generated function body, where the first function used a
goto but the second does not. Change the code to just check
for the known conditions which cause an error check to be
needed. Besides, it's slightly more efficient to use plain
checks than regular expression searching.

No change to generated code.

Backports commit f9e6102b48f21e464a847a858a456c521e7a83e5 from qemu
2018-02-19 19:07:03 -05:00
Eric Blake 7a4feccf64
qapi: More idiomatic string operations
Rather than slicing the end of a string, we can use python's
endswith(). And rather than creating a set of characters,
we can search for a character within a string.

Backports commit 8712fa5333ad348da20034b717dd814219d1ec11 from qemu
2018-02-19 19:06:20 -05:00
Eric Blake 5e62ed79f9
qapi: Track location that created an implicit type
A future patch will move some error checking from the parser
to the various QAPISchema*.check() methods, which run only
after parsing completes. It will thus be possible to create
a python instance representing an implicit QAPI type that
parses fine but will fail validation during check(). Since
all errors have to have an associated 'info' location, we
need a location to be associated with those implicit types.
The intuitive info to use is the location of the enclosing
entity that caused the creation of the implicit type.

Note that we do not anticipate builtin types being used in
an error message (as they are not part of the user's QAPI
input, the user can't cause a semantic error in their
behavior), so we exempt those types from requiring info, by
setting a flag to track the completion of _def_predefineds(),
and tracking that flag in _def_entity().

No change to the generated code.

Backports commit 99df5289d8c7ebf373c3570d8fba3f3a73360281 from qemu
2018-02-19 19:04:41 -05:00
Eric Blake 738fd1e5ad
qapi: Create simple union type member earlier
For simple unions, we were creating the implicit 'type' tag
member during the QAPISchemaObjectTypeVariants constructor.
This is different from every other implicit QAPISchemaEntity
object, which get created by QAPISchema methods. Hoist the
creation to the caller (renaming _make_tag_enum() to
_make_implicit_tag()), and pass the entity rather than the
string name, so that we have the nice property that no
entities are created as a side effect within a different
entity. A later patch will then have an easier time of
associating location info with each entity creation.

No change to generated code.

Backports commit 46292ba75c515baf733df18644052b2ce9492728 from qemu
2018-02-19 18:57:56 -05:00
Eric Blake b9b76f9b4b
qapi: Lazy creation of array types
Commit ac88219a had several TODO markers about whether we needed
to automatically create the corresponding array type alongside
any other type. It turns out that most of the time, we don't!

There are a few exceptions: 1) We have a few situations where we
use an array type in internal code but do not expose that type
through QMP; fix it by declaring a dummy type that forces the
generator to see that we want to use the array type.

2) The builtin arrays (such as intList for QAPI ['int']) must
always be generated, because of the way our QAPI_TYPES_BUILTIN
compile guard works: we have situations (at the very least
tests/test-qmp-output-visitor.c) that include both top-level
"qapi-types.h" (via "error.h") and a secondary
"test-qapi-types.h". If we were to only emit the builtin types
when used locally, then the first .h file would not include all
types, but the second .h does not declare anything at all because
the first .h set QAPI_TYPES_BUILTIN, and we would end up with
compilation error due to things like unknown type 'int8List'.

Actually, we may need to revisit how we do type guards, and
change from a single QAPI_TYPES_BUILTIN over to a different
usage pattern that does one #ifdef per qapi type - right now,
the only types that are declared multiple times between two qapi
.json files for inclusion by a single .c file happen to be the
builtin arrays. But now that we have QAPI 'include' statements,
it is logical to assume that we will soon reach a point where
we want to reuse non-builtin types (yes, I'm thinking about what
it will take to add introspection to QGA, where we will want to
reuse the SchemaInfo type and friends). One #ifdef per type
will help ensure that generating the same qapi type into more
than one qapi-types.h won't cause collisions when both are
included in the same .c file; but we also have to solve how to
avoid creating duplicate qapi-types.c entry points. So that
is a problem left for another day.

Generated code for qapi-types and qapi-visit is drastically
reduced; less than a third of the arrays that were blindly
created were actually needed (a quick grep shows we dropped
from 219 to 69 *List types), and the .o files lost more than
30% of their bulk. [For best results, diff the generated
files with 'git diff --patience --no-index pre post'.]

Interestingly, the introspection output is unchanged - this is
because we already cull all types that are not indirectly
reachable from a command or event, so introspection was already
using only a subset of array types. The subset of types
introspected is now a much larger percentage of the overall set
of array types emitted in qapi-types.h (since the larger set
shrunk), but still not 100% (evidence that the array types
emitted for our new Dummy structs, and the new struct itself,
don't affect QMP).

Backports commit 9f08c8ec73878122ad4b061ed334f0437afaaa32 from qemu
2018-02-19 18:55:35 -05:00
Eric Blake dc65960e1f
qapi: Don't use info as witness of implicit object type
A future patch will enable error reporting from the various
QAPISchema*.check() methods. But to report an error related
to an implicit type, we'll need to associate a location with
the type (the same location as the top-level entity that is
causing the creation of the implicit type), and once we do
that, keying off of whether foo.info exists is no longer a
viable way to determine if foo is an implicit type.

Instead, add an is_implicit() method to QAPISchemaEntity, and use it.
It can be overridden later for ObjectType and EnumType, when implicit
instances of those classes gain info.

Backports commit 49823c4b4304a3e4aa5d67e089946b12d6a52d64 from qemu
2018-02-19 18:53:06 -05:00
Eric Blake 3d11f7173d
qapi: Prepare for errors during check()
The next few patches will start migrating error checking from
ad hoc parse methods into the QAPISchema*.check() methods. But
for an error message to display, we first have to fix the
overall 'try' to catch those errors. We also want to enable a
few more assertions, such as making sure every attempt to
raise a semantic error is passed a valid location info, or that
various preconditions hold.

The general approach for moving error checking will then be to
relax an assertion into an if that raises an exception if the
condition does not hold, and removing the counterpart ad hoc
check done during the parse phase.

Backports commit 7618b91ff80ec42b84b29be24d8ef53ddb377110 from qemu
2018-02-19 18:50:23 -05:00
Eric Blake 9d0c5746ff
qapi: Use predicate callback to determine visit filtering
Previously, qapi-types and qapi-visit filtered out implicit
objects during visit_object_type() by using 'info' (works since
implicit objects do not [yet] have associated info); meanwhile
qapi-introspect filtered out all schema types on the first pass
by returning a python type from visit_begin(), which was then
used at a distance in QAPISchema.visit() to do the filtering.

Rather than keeping these ad hoc approaches, add a new visitor
callback visit_needed() which returns False to skip a given
entity, and which defaults to True unless overridden. Use the
new mechanism to simplify all three filtering visitors.

No change to the generated code.

Backports commit 25a0d9c977c2f5db914b0a1619759fd77d97b016 from qemu
2018-02-19 18:49:08 -05:00
Eric Blake f371fa9105
qapi: Simplify gen_visit_fields() error handling
Since we have consolidated all generated code to use 'err' as
the name of the local variable for error detection, we can
simplify the decision on whether to skip error detection (useful
for deallocation paths) to be a boolean.

Backports commit 18bdbc3ac8b477e160d56aa6ecd6942495ce44d0 from qemu
2018-02-19 18:45:05 -05:00
Eric Blake 4ca10929a7
qapi: Share gen_visit_fields()
Consolidate the code between visit, command marshalling, and
event generation that iterates over the members of a struct.
It reduces code duplication in the generator, so that a future
patch can reduce the size of generated code while touching only
one instead of three locations.

There are no changes to the generated marshal code.

The visitor code becomes slightly more verbose, but remains
semantically equivalent, and is actually easier to read as
it follows a more common idiom:

| visit_optional(v, &(*obj)->has_device, "device", &err);
|- if (!err && (*obj)->has_device) {
|- visit_type_str(v, &(*obj)->device, "device", &err);
|- }
| if (err) {
| goto out;
| }
|+ if ((*obj)->has_device) {
|+ visit_type_str(v, &(*obj)->device, "device", &err);
|+ if (err) {
|+ goto out;
|+ }
|+ }

The event code becomes slightly more verbose, but this is
arguably a bug fix: although the visitors are not well
documented, use of an optional member should not be attempted
unless guarded by a prior call to visit_optional(). Works only
because the output qmp visitor has a no-op visit_optional():

|+ visit_optional(v, &has_offset, "offset", &err);
|+ if (err) {
|+ goto out;
|+ }
| if (has_offset) {
| visit_type_int(v, &offset, "offset", &err);

Backports commit 82ca8e469666b169ccf818a0e36136aee97d7db0 from qemu
2018-02-19 18:41:41 -05:00
Eric Blake 13b3a6c92f
qapi: Consistent generated code: minimize push_indent() usage
We had some pointless differences in the generated code for visit,
command marshalling, and events; unifying them makes it easier for
future patches to consolidate to common helper functions.
This is one patch of a series to clean up these differences.

This patch reduces the number of push_indent()/pop_indent() pairs
so that generated code is typically already at its natural output
indentation in the python files. It is easier to reason about
generated code if the reader does not have to track how much
spacing will be inserted alongside the code, and moreso when all
of the generators use the same patterns (qapi-type and qapi-event
were already using in-place indentation).

Arguably, the resulting python may be a bit harder to read with C
code at the same indentation as python; on the other hand, not
having to think about push_indent() is a win, and most decent
editors provide syntax highlighting that makes it easier to
visually distinguish python code from string literals that will
become C code.

There is no change to the generated output.

Backports commit 05372f708a8cb3556e4d67458de79417dadf241f from qemu
2018-02-19 18:38:48 -05:00
Eric Blake ec89e19b30
qapi: Consistent generated code: prefer common indentation
We had some pointless differences in the generated code for visit,
command marshalling, and events; unifying them makes it easier for
future patches to consolidate to common helper functions.
This is one patch of a series to clean up these differences.

This patch adjusts gen_visit_union() to use the same indentation
as other functions, namely, by jumping early to the error label
if the object was not set rather than placing the rest of the
body inside an if for when it is set.

No change in semantics to the generated code.

Backports commit e36c714e6aad7c9266132350833e2f263f6d8874 from qemu
2018-02-19 18:26:14 -05:00
Eric Blake 53c2c709af
qapi: Consistent generated code: prefer common labels
We had some pointless differences in the generated code for visit,
command marshalling, and events; unifying them makes it easier for
future patches to consolidate to common helper functions.
This is one patch of a series to clean up these differences.

This patch names the goto labels 'out' (not 'clean') and 'out_obj'
(not 'out_end'). Additionally, the generator was inconsistent on
whether labels had a leading space [our HACKING is silent; while
emacs 'gnu' style adds the space to avoid littering column 1].
For minimal churn, prefer no leading space; this also matches
the style that is more prevalent in current qemu.git.

No change in semantics to the generated code.

Backports commit f782399cb4fa3fc4182cb046817f65a6db92ab07 from qemu
2018-02-19 18:23:15 -05:00
Eric Blake 4e9c5e4d52
qapi: Consistent generated code: prefer visitor 'v'
We had some pointless differences in the generated code for visit,
command marshalling, and events; unifying them makes it easier for
future patches to consolidate to common helper functions.
This is one patch of a series to clean up these differences.

This patch names the local visitor variable 'v' rather than 'm'.
Related objects, such as 'QapiDeallocVisitor', are also named by
their initials instead of an unrelated leading m.

No change in semantics to the generated code.

Backports commit f8b7f1a8eafa9f565ebecfe409e8741d38cd786b from qemu
2018-02-19 18:21:53 -05:00
Eric Blake bc8a7ae5f9
qapi: Consistent generated code: prefer error 'err'
We had some pointless differences in the generated code for visit,
command marshalling, and events; unifying them makes it easier for
future patches to consolidate to common helper functions.
This is one patch of a series to clean up these differences.

This patch consistently names the local error variable 'err' rather
than 'local_err'.

No change in semantics to the generated code.

Backports commit 2a0f50e8d973b01eda4c63bac4a5c79ea0f584ef from qemu
2018-02-19 18:15:10 -05:00
Eric Blake 4294815ee3
qapi: Reuse code for flat union base validation
Rather than open-code the check for a valid base type, we
should reuse the common functionality. This allows for
consistent error messages, and also makes it easier for a
later patch to turn on support for inline anonymous base
structures.

Test flat-union-inline is updated to test only one feature
(anonymous branch dictionaries), which can be implemented
independently (test flat-union-bad-base already covers the
idea of an anonymous base dictionary).

Backports commit 376863ef4895ae709aadb6f26365a5973310ef09 from qemu
2018-02-19 18:14:53 -05:00
Eric Blake c09db972fe
qapi: Avoid assertion failure on union 'type' collision
The previous commit added two tests that triggered an assertion
failure. It's fairly straightforward to avoid the failure by
just outright forbidding the collision between a union's tag
values and its discriminator name (including the implicit name
'kind' supplied for simple unions [*]). Ultimately, we'd like
to move the collision detection into QAPISchema*.check(), but
for now it is easier just to enhance the existing checks.

[*] Of course, down the road, we have plans to rename the simple
union tag name to 'type' to match the QMP wire name, but the
idea of the collision will still be present even then.

Technically, we could avoid the collision by naming the C union
members representing each enum value as '_case_value' rather
than 'value'; but until we have an actual qapi client (and not
just our testsuite) that has a legitimate reason to match a
case label to the name of a QMP key and needs the name munging
to satisfy the compiler, it's easier to just reject the qapi
as invalid.

Backports commit 7b2a5c2f9a52c4a08630fa741052f03fe5d3cc8a from qemu
2018-02-19 18:09:13 -05:00
Eric Blake 8fce54a867
qapi: Clean up qapi.py per pep8
Silence pep8, and make pylint a bit happier. Just style cleanups,
plus killing a useless comment in camel_to_upper(); no semantic
changes.

Backports commit 437db2549be383e52acad6cd4bf2862e98fdfc93 from qemu
2018-02-19 18:07:55 -05:00
Eric Blake 07f0fa3ee9
qapi: Invoke exception superclass initializer
pylint recommends that every exception class should explicitly
invoke the superclass __init__, even though things seem to work
fine without it.

Backports commit 59b00542659c8947f9d4e8c28d2d528ab3ab61a5 from qemu
2018-02-19 17:57:21 -05:00
Eric Blake de2b67e528
qapi: Improve 'include' error message
Use of '"...%s" % include' to print non-strings can lead to
ugly messages, such as this (if the .json change is applied
without the qapi.py change):
 Expected a file name (string), got: OrderedDict()

Better is to just omit the actual non-string value in the
message.

Backports commit 7408fb67c0f9403f6e40aecf97cf798fc14e2cd8 from qemu
2018-02-19 17:56:17 -05:00
Markus Armbruster 02e411f666
qapi: New QMP command query-qmp-schema for QMP introspection
qapi/introspect.json defines the introspection schema. It's designed
for QMP introspection, but should do for similar uses, such as QGA.

The introspection schema does not reflect all the rules and
restrictions that apply to QAPI schemata. A valid QAPI schema has an
introspection value conforming to the introspection schema, but the
converse is not true.

Introspection lowers away a number of schema details, and makes
implicit things explicit:

* The built-in types are declared with their JSON type.

All integer types are mapped to 'int', because how many bits we use
internally is an implementation detail. It could be pressed into
external interface service as very approximate range information,
but that's a bad idea. If we need range information, we better do
it properly.

* Implicit type definitions are made explicit, and given
auto-generated names:

- Array types, named by appending "List" to the name of their
element type, like in generated C.

- The enumeration types implicitly defined by simple union types,
named by appending "Kind" to the name of their simple union type,
like in generated C.

- Types that don't occur in generated C. Their names start with ':'
so they don't clash with the user's names.

* All type references are by name.

* The struct and union types are generalized into an object type.

* Base types are flattened.

* Commands take a single argument and return a single result.

Dictionary argument or list result is an implicit type definition.

The empty object type is used when a command takes no arguments or
produces no results.

The argument is always of object type, but the introspection schema
doesn't reflect that.

The 'gen': false directive is omitted as implementation detail.

The 'success-response' directive is omitted as well for now, even
though it's not an implementation detail, because it's not used by
QMP.

* Events carry a single data value.

Implicit type definition and empty object type use, just like for
commands.

The value is of object type, but the introspection schema doesn't
reflect that.

* Types not used by commands or events are omitted.

Indirect use counts as use.

* Optional members have a default, which can only be null right now

Instead of a mandatory "optional" flag, we have an optional default.
No default means mandatory, default null means optional without
default value. Non-null is available for optional with default
(possible future extension).

* Clients should *not* look up types by name, because type names are
not ABI. Look up the command or event you're interested in, then
follow the references.

TODO Should we hide the type names to eliminate the temptation?

New generator scripts/qapi-introspect.py computes an introspection
value for its input, and generates a C variable holding it.

It can generate awfully long lines. Marked TODO.

A new test-qmp-input-visitor test case feeds its result for both
tests/qapi-schema/qapi-schema-test.json and qapi-schema.json to a
QmpInputVisitor to verify it actually conforms to the schema.

New QMP command query-qmp-schema takes its return value from that
variable. Its reply is some 85KiBytes for me right now.

If this turns out to be too much, we have a couple of options:

* We can use shorter names in the JSON. Not the QMP style.

* Optionally return the sub-schema for commands and events given as
arguments.

Right now qmp_query_schema() sends the string literal computed by
qmp-introspect.py. To compute sub-schema at run time, we'd have to
duplicate parts of qapi-introspect.py in C. Unattractive.

* Let clients cache the output of query-qmp-schema.

It changes only on QEMU upgrades, i.e. rarely. Provide a command
query-qmp-schema-hash. Clients can have a cache indexed by hash,
and re-query the schema only when they don't have it cached. Even
simpler: put the hash in the QMP greeting.

Backports commit 39a181581650f4d50f4445bc6276d9716cece050 from qemu
2018-02-19 17:54:03 -05:00
Markus Armbruster 8115f998e9
qapi: Pseudo-type '**' is now unused, drop it
'gen': false needs to stay for now, because netdev_add is still using
it.

Backports commit 2d21291ae645955fcc4652ebfec81ad338169ac6 from qemu
2018-02-19 17:49:46 -05:00
Markus Armbruster e9dac6908f
qom: Don't use 'gen': false for qom-get, qom-set, object-add
With the previous commit, the generated marshalers just work, and save
us a bit of handwritten code.

Backports commit 6eb3937e9b20319e1c4f4d53e906fda8f5ccda10 from qemu
2018-02-19 17:47:59 -05:00
Markus Armbruster f93438ba43
qapi: Introduce a first class 'any' type
It's first class, because unlike '**', it actually works, i.e. doesn't
require 'gen': false.

'**' will go away next.

Backports commit 28770e057f265a4e70bcbdfc2447cce7b5f2dc19 from qemu
2018-02-19 17:46:58 -05:00
Markus Armbruster 66def00922
qapi: De-duplicate parameter list generation
Generated qapi-event.[ch] lose line breaks. No change otherwise.

Backports commit 03b4367a556179e3e59affa535493427bd009e9d from qemu
2018-02-19 17:38:52 -05:00
Markus Armbruster b4187c01da
qapi-visit: Rearrange code a bit
Move gen_visit_decl() to a better place. Inline
generate_visit_struct_body().

Backports commit 60f8546acd113e636bf2ba8af991ebe0f6e8ad66 from qemu
2018-02-19 17:37:09 -05:00
Markus Armbruster d6866a50f6
qapi: Clean up after recent conversions to QAPISchemaVisitor
Generate just 'FOO' instead of 'struct FOO' when possible.

Drop helper functions that are now unused.

Make pep8 and pylint reasonably happy.

Rename generate_FOO() functions to gen_FOO() for consistency.

Use more consistent and sensible variable names.

Consistently use c_ for mapping keys when their value is a C
identifier or type.

Simplify gen_enum() and gen_visit_union()

Consistently use single quotes for C text string literals.

Backports commit e98859a9b96d71dea8f9af43325edd43c7effe66 from qemu
2018-02-19 17:34:32 -05:00
Markus Armbruster 64e9fceab9
qapi: Replace dirty is_c_ptr() by method c_null()
is_c_ptr() looks whether the end of the C text for the type looks like
a pointer. Works, but is fragile.

We now have a better tool: use QAPISchemaType method c_null(). The
initializers for non-pointers become prettier: 0, false or the
enumeration constant with the value 0 instead of {0}.

Backports commit 5710153e7310995b5d4127af267e36d8529b3b30 from qemu
2018-02-19 17:17:40 -05:00
Markus Armbruster abfa5da7da
qapi-event: Convert to QAPISchemaVisitor, fixing data with base
Fixes events whose data is struct with base to include the struct's
base members. Test case is qapi-schema-test.json's event
__org.qemu_x-command:

{ 'event': '__ORG.QEMU_X-EVENT', 'data': '__org.qemu_x-Struct' }

{ 'struct': '__org.qemu_x-Struct', 'base': '__org.qemu_x-Base',
'data': { '__org.qemu_x-member2': 'str' } }

{ 'struct': '__org.qemu_x-Base',
'data': { '__org.qemu_x-member1': '__org.qemu_x-Enum' } }

Patch's effect on generated qapi_event_send___org_qemu_x_event():

-void qapi_event_send___org_qemu_x_event(const char *__org_qemu_x_member2,
+void qapi_event_send___org_qemu_x_event(__org_qemu_x_Enum __org_qemu_x_member1,
+ const char *__org_qemu_x_member2,
Error **errp)
{
QDict *qmp;
@@ -224,6 +225,10 @@ void qapi_event_send___org_qemu_x_event(
goto clean;
}

+ visit_type___org_qemu_x_Enum(v, &__org_qemu_x_member1, "__org.qemu_x-member1", &local_err);
+ if (local_err) {
+ goto clean;
+ }
visit_type_str(v, (char **)&__org_qemu_x_member2, "__org.qemu_x-member2", &local_err);
if (local_err) {
goto clean;

Code is generated in a different order now, but that doesn't matter.

Backports commit 05f43a960877cf941635324b2d0a74c0d0f7128e from qemu
2018-02-19 17:16:31 -05:00
Markus Armbruster 533bf08ff1
qapi-event: Eliminate global variable event_enum_value
Backports commit 7b24626cd019ed5084c8e3370999176a1ebd44be from qemu
2018-02-19 17:13:37 -05:00
Markus Armbruster 782a549898
qapi: De-duplicate enum code generation
Duplicated in commit 21cd70d. Yes, we can't import qapi-types, but
that's no excuse. Move the helpers from qapi-types.py to qapi.py, and
replace the duplicates in qapi-event.py.

The generated event enumeration type's lookup table becomes
const-correct (see commit 2e4450f), and uses explicit indexes instead
of relying on order (see commit 912ae9c).

Backports commit efd2eaa6c2992c214a13f102b6ddd4dca4697fb3 from qemu
2018-02-19 17:11:05 -05:00
Markus Armbruster baa36c6c88
qapi-visit: Convert to QAPISchemaVisitor, fixing bugs
Fixes flat unions to visit the base's base members (the previous
commit merely added them to the struct). Same test case.

Patch's effect on visit_type_UserDefFlatUnion():

static void visit_type_UserDefFlatUnion_fields(Visitor *m, UserDefFlatUnion **obj, Error **errp)
{
Error *err = NULL;

+ visit_type_int(m, &(*obj)->integer, "integer", &err);
+ if (err) {
+ goto out;
+ }
visit_type_str(m, &(*obj)->string, "string", &err);
if (err) {
goto out;

Test cases updated for the bug fix.

Fixes alternates to generate a visitor for their implicit enumeration
type. None of them are currently used, obviously. Example:
block-core.json's BlockdevRef now generates
visit_type_BlockdevRefKind().

Code is generated in a different order now, and therefore has got a
few new forward declarations. Doesn't matter.

The guard QAPI_VISIT_BUILTIN_VISITOR_DECL is renamed to
QAPI_VISIT_BUILTIN.

The previous commit's two ugly special cases exist here, too. Mark
both TODO.

Backports commit 441cbac0c7e641780decbc674a9a68c6a5200f71 from qemu
2018-02-19 17:04:59 -05:00
Markus Armbruster 03634275b1
qapi-types: Convert to QAPISchemaVisitor, fixing flat unions
Fixes flat unions to get the base's base members. Test case is from
commit 2fc0043, in qapi-schema-test.json:

{ 'union': 'UserDefFlatUnion',
'base': 'UserDefUnionBase',
'discriminator': 'enum1',
'data': { 'value1' : 'UserDefA',
'value2' : 'UserDefB',
'value3' : 'UserDefB' } }

{ 'struct': 'UserDefUnionBase',
'base': 'UserDefZero',
'data': { 'string': 'str', 'enum1': 'EnumOne' } }

{ 'struct': 'UserDefZero',
'data': { 'integer': 'int' } }

Patch's effect on UserDefFlatUnion:

struct UserDefFlatUnion {
/* Members inherited from UserDefUnionBase: */
+ int64_t integer;
char *string;
EnumOne enum1;
/* Own members: */
union { /* union tag is @enum1 */
void *data;
UserDefA *value1;
UserDefB *value2;
UserDefB *value3;
};
};

Flat union visitors remain broken. They'll be fixed next.

Code is generated in a different order now, but that doesn't matter.

The two guards QAPI_TYPES_BUILTIN_STRUCT_DECL and
QAPI_TYPES_BUILTIN_CLEANUP_DECL are replaced by just
QAPI_TYPES_BUILTIN.

Two ugly special cases for simple unions now stand out like sore
thumbs:

1. The type tag is named 'type' everywhere, except in generated C,
where it's 'kind'.

2. QAPISchema lowers simple unions to semantically equivalent flat
unions. However, the C generated for a simple unions differs from
the C generated for its equivalent flat union, and we therefore
need special code to preserve that pointless difference for now.

Mark both TODO.

Backports commit 2b162ccbe875e5323fc04c1009addbdea4d35220 from qemu
2018-02-19 16:58:34 -05:00
Lioncash 72f6d68002
qapi: New QAPISchemaVisitor
The visitor will help keeping the code generation code simple and
reasonably separated from QAPISchema details.

Backports commit 3f7dc21bee1e930d5cccf607b8f83831c3bbdb09 from qemu
2018-02-19 16:50:02 -05:00
Markus Armbruster 8ce395e073
qapi: QAPISchema code generation helper methods
New methods c_name(), c_type(), c_null(), json_type(),
alternate_qtype().

Backports commit f51d8c3db11b0f3052b3bb4b8b0c7f0bc76f7136 from qemu
2018-02-19 16:47:35 -05:00
Markus Armbruster a3660e451d
qapi: New QAPISchema intermediate reperesentation
The QAPI code generators work with a syntax tree (nested dictionaries)
plus a few symbol tables (also dictionaries) on the side.

They have clearly outgrown these simple data structures. There's lots
of rummaging around in dictionaries, and information is recomputed on
the fly. For the work I'm going to do, I want more clearly defined
and more convenient interfaces.

Going forward, I also want less coupling between the back-ends and the
syntax tree, to make messing with the syntax easier.

Create a bunch of classes to represent QAPI schemata.

Have the QAPISchema initializer call the parser, then walk the syntax
tree to create the new internal representation, and finally perform
semantic analysis.

Shortcut: the semantic analysis still relies on existing check_exprs()
to do the actual semantic checking. All this code needs to move into
the classes. Mark as TODO.

Simple unions are lowered to flat unions. Flat unions and structs are
represented as a more general object type.

Catching name collisions in generated code would be nice. Mark as
TODO.

We generate array types eagerly, even though most of them aren't used.
Mark as TODO.

Nothing uses the new intermediate representation just yet, thus no
change to generated files.

Backports commit ac88219a6c78302c693fb60fe6cf04358540fbce from qemu
2018-02-19 16:43:30 -05:00
Markus Armbruster 448a2e95ac
qapi: Rename class QAPISchema to QAPISchemaParser
I want to name a new class QAPISchema.

While there, make it a new-style class.

Backports commit a4bcb2080d5c1d08bab512d76fb260296e2cae74 from qemu
2018-02-19 16:41:00 -05:00
Daniel P. Berrange fe90a5c914
qapi: allow override of default enum prefix naming
The camel_to_upper() method applies some heuristics to turn
a mixed case type name into an all-uppercase name. This is
used for example, to generate enum constant name prefixes.

The heuristics don't also generate a satisfactory name
though. eg

{ 'enum': 'QCryptoTLSCredsEndpoint',
'data': ['client', 'server']}

Results in Q_CRYPTOTLS_CREDS_ENDPOINT_CLIENT. This has
an undesirable _ after the initial Q and is missing an
_ between the CRYPTO & TLS strings.

Rather than try to add more and more heuristics to try
to cope with this, simply allow the QAPI schema to
specify the desired enum constant prefix explicitly.

eg

{ 'enum': 'QCryptoTLSCredsEndpoint',
'prefix': 'QCRYPTO_TLS_CREDS_ENDPOINT',
'data': ['client', 'server']}

Now gives the QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT name.

Backports commit 351d36e454cddc67a1675740916636a7ccbf1c4b from qemu
2018-02-19 16:38:48 -05:00
Markus Armbruster d59948f245
qapi: Fix cgen() for Python older than 2.7
A feature new in Python 2.7 crept into commit 77e703b: re.subn()'s
fifth argument.  Avoid that, use re.compile().

Backports commit 2752e5bedb26fa0c7291f810f9f534b688b2f1d2 from qemu
2018-02-19 16:34:17 -05:00
Markus Armbruster 809b439562
qapi: Generators crash when --output-dir isn't given, fix
Backports commit c4f498fe8532cdacc609262b104322911108df54 from qemu
2018-02-19 16:32:50 -05:00
Markus Armbruster 741783073f
qapi: Simplify error reporting for array types
check_type() first checks and peels off the array type, then checks
the element type. For two out of four error messages, it takes pains
to report errors for "array of T" instead of just T. Odd. Let's
examine the errors.

* Unknown element type, e.g.
tests/qapi-schema/args-array-unknown.json:

Member 'array' of 'data' for command 'oops' uses unknown type
'array of NoSuchType'

To make sense of this, you need to know that 'array of NoSuchType'
refers to '[NoSuchType]'. Easy enough. However, simply reporting

Member 'array' of 'data' for command 'oops' uses unknown type
'NoSuchType'

is at least as easy to understand.

* Element type's meta-type is inadmissible, e.g.
tests/qapi-schema/returns-whitelist.json:

'returns' for command 'no-way-this-will-get-whitelisted' cannot
use built-in type 'array of int'

'array of int' is technically not a built-in type, but that's
pedantry. However, simply reporting

'returns' for command 'no-way-this-will-get-whitelisted' cannot
use built-in type 'int'

avoids the issue, and is at least as easy to understand.

* The remaining two errors are unreachable, because the array checking
ensures that value is a string.

Thus, reporting some errors for "array of T" instead of just T works,
but doesn't really improve things. Drop it.

Backports commit eddf817bd823a90df209dfbdc2a0b2ec33b7cb77 from qemu
2018-02-19 16:31:44 -05:00
Markus Armbruster 630b56b4a2
qapi: Fix errors for non-string, non-dictionary members
Backports commit c6b71e5ae73802057d700e2419b80aef1651f213 from qemu
2018-02-19 16:30:50 -05:00
Markus Armbruster 16619a738e
qapi: Drop one of two "simple union must not have base" checks
The first check ensures the second one can't trigger. Drop the first
one, because the second one is in a more logical place, and emits a
nicer error message.

Backports commit 65fbe125451da9421070ab03944c9600a264eefc from qemu
2018-02-19 16:29:58 -05:00
Markus Armbruster 46cf5ed6ae
qapi: Generated code cleanup
Clean up white-space, brace placement, and superfluous #ifdef
QAPI_TYPES_BUILTIN_CLEANUP_DEF.

Backports commit 3a864e7c52af15017d5082a9ee39a7919f46d2b5 from qemu
2018-02-19 16:29:13 -05:00
Markus Armbruster c5e8b70b5a
qapi: Command returning anonymous type doesn't work, outlaw
Reproducer: with

{ 'command': 'user_def_cmd4', 'returns': { 'a': 'int' } }

added to qapi-schema-test.json, qapi-commands.py dies when it tries to
generate the command handler function

Traceback (most recent call last):
File "/work/armbru/qemu/scripts/qapi-commands.py", line 359, in <module>
ret = generate_command_decl(cmd['command'], arglist, ret_type) + "\n"
File "/work/armbru/qemu/scripts/qapi-commands.py", line 29, in generate_command_decl
ret_type=c_type(ret_type), name=c_name(name),
File "/work/armbru/qemu/scripts/qapi.py", line 927, in c_type
assert isinstance(value, str) and value != ""
AssertionError

because the return type doesn't exist.

Simply outlaw this usage, and drop or dumb down test cases accordingly.

Backports commit 9b090d42aea9a0abbf39a1d75561a186057b5fe6 from qemu
2018-02-19 16:24:14 -05:00
Markus Armbruster 8d992dfa48
qapi: Fix to reject union command and event arguments
A command's or event's 'data' must be a struct type, given either as a
dictionary, or as struct type name.

Commit dd883c6 tightened the checking there, but not enough: we still
accept 'union'. Fix to reject it.

We may want to support union types there, but we'll have to extend
qapi-commands.py and qapi-events.py for it.

Backports commit 315932b5edb86597adafbd1faa2d29c46499d8c3 from qemu
2018-02-19 16:23:24 -05:00
Markus Armbruster eed32a1c57
qapi: Document flaws in checking of names
We don't actually enforce our "other than downstream extensions [...],
all names should begin with a letter" rule. Add a FIXME.

We should reject names that differ only in '_' vs. '.' vs. '-',
because they're liable to clash in generated C. Add a FIXME.

Backports commit d90675fa4bc256238b3dd3a7fdd5f9029eca00b8 from qemu
2018-02-19 16:22:35 -05:00
Eric Blake 6e85e420fb
qapi: Document shortcoming with union 'data' branch
Add a FIXME to remind us to fully audit whether removing the
'void *data' branch of each qapi union type can be done safely.

Backports commit ca56a822dd538017715345cbbe1f8829e0cc2742 from qemu
2018-02-19 16:21:22 -05:00
Markus Armbruster 94b19608af
qapi-visit: Fix two name arguments passed to visitors
The generated code passes mangled schema names to visit_type_enum()
and union's visit_start_struct(). Fix it to pass the names
unadulterated, like we do everywhere else.

Only qapi-schema-test.json actually has names where this makes a
difference: enum __org.qemu_x-Enum, flat union __org.qemu_x-Union2,
simple union __org.qemu_x-Union1 and its implicit enum
__org.qemu_x-Union1Kind.

Backports commit 40b3adec13a9e022ff5a2e2b81c243fc0a026746 from qemu
2018-02-19 16:20:10 -05:00
Markus Armbruster 54ce4b3f00
qapi-visit: Replace list implicit_structs by set
Use set because that's what it is. While there, rename to
implicit_structs_seen.

Backports commit 8c07eddc619d618965fdd7a96bfe3b5c59f42b52 from qemu
2018-02-19 16:17:37 -05:00
Markus Armbruster 23d14a2921
qapi-visit: Fix generated code when schema has forward refs
The visit_type_implicit_FOO() are generated on demand, right before
their first use. Used by visit_type_STRUCT_fields() when STRUCT has
base FOO, and by visit_type_UNION() when flat UNION has member a FOO.

If the schema defines FOO after its first use as struct base or flat
union member, visit_type_implicit_FOO() calls
visit_type_implicit_FOO() before its definition, which doesn't
compile.

Rearrange qapi-schema-test.json to demonstrate the bug.

Fix by generating the necessary forward declaration.

Backports commit 8c3f8e77215bfedb7854221868f655e148506936 from qemu
2018-02-19 16:16:19 -05:00
Markus Armbruster 389afaa743
qapi: Generate a nicer struct for flat unions
The struct generated for a flat union is weird: the members of its
base are at the end, except for the union tag, which is at the
beginning.

Example: qapi-schema-test.json has

{ 'struct': 'UserDefUnionBase',
'data': { 'string': 'str', 'enum1': 'EnumOne' } }

{ 'union': 'UserDefFlatUnion',
'base': 'UserDefUnionBase',
'discriminator': 'enum1',
'data': { 'value1' : 'UserDefA',
'value2' : 'UserDefB',
'value3' : 'UserDefB' } }

We generate:

struct UserDefFlatUnion
{
EnumOne enum1;
union {
void *data;
UserDefA *value1;
UserDefB *value2;
UserDefB *value3;
};
char *string;
};

Change to put all base members at the beginning, unadulterated. Not
only is this easier to understand, it also permits casting the flat
union to its base, if that should become useful.

We now generate:

struct UserDefFlatUnion
{
/* Members inherited from UserDefUnionBase: */
char *string;
EnumOne enum1;
/* Own members: */
union { /* union tag is @enum1 */
void *data;
UserDefA *value1;
UserDefB *value2;
UserDefB *value3;
};
};

Backports commit 1e6c1616a91cdcbe9a8387541f7689b8c11632aa from qemu
2018-02-19 16:14:51 -05:00
Markus Armbruster 8b7252d8c8
qapi: Fix generated code when flat union has member 'kind'
A flat union's tag member gets renamed to 'kind' in the generated
code. Breaks when another member named 'kind' exists.

Example, adapted from qapi-schema-test.json:

{ 'struct': 'UserDefUnionBase',
'data': { 'kind': 'str', 'enum1': 'EnumOne' } }

We generate:

struct UserDefFlatUnion
{
EnumOne kind;
union {
void *data;
UserDefA *value1;
UserDefB *value2;
UserDefB *value3;
};
char *kind;
};

Kill the silly rename.

Backports commit 0f61af3eb396ae163cd1572ce12e05f5d08d7c15 from qemu
2018-02-19 16:13:07 -05:00
Markus Armbruster b190e4887e
qapi: Drop unused and useless parameters and variables
gen_sync_call()'s parameter indent is useless: gen_sync_call() uses it
only as optional argument for push_indent() and pop_indent(), their
default is four, and gen_sync_call()'s only caller passes four. Drop
the parameter.

gen_visitor_input_containers_decl()'s parameter obj is always
"QOBJECT(args)". Use that, and drop the parameter.

Drop unused parameters of gen_marshal_output(),
gen_marshal_input_decl(), generate_visit_struct_body(),
generate_visit_list(), generate_visit_enum(), generate_declaration(),
generate_enum_declaration(), generate_decl_enum().

Drop unused variables in generate_event_enum_lookup(),
generate_enum_lookup(), generate_visit_struct_fields(), check_event().

Backports commit 5aa05d3f72e556752167f7005d6a3dea0f4432c5 from qemu
2018-02-19 16:11:35 -05:00
Markus Armbruster cf9d457200
qapi: Reject -p arguments that break qapi-event.py
qapi-event.py breaks when you ask for a funny prefix like '@'.
Protect it.

Backports commit 1cf47a15f18312436c7fa2d97be5fbe6df0292f5 from qemu
2018-02-19 16:07:40 -05:00
Markus Armbruster 2c3f6e4175
qapi-event: Clean up how name of enum QAPIEvent is made
Use c_name() instead of ad hoc code. Doesn't upcase the -p prefix,
which is an improvement in my book. Unbreaks prefix containing '.',
but other funny characters remain broken. To be fixed next.

Backports commit 016a335bd8ca624f43adbb08fa1698c29ec52a1a from qemu
2018-02-19 16:06:35 -05:00
Markus Armbruster 6dcb71a788
qapi: Simplify guardname()
The guards around built-in declarations lose their _H. It never made
much sense anyway.

Backports commit 00dfc3b2c272d98556ec6095d56bdd8b036babf9 from qemu
2018-02-19 16:05:52 -05:00
Markus Armbruster e100831af9
qapi: Clean up cgen() and mcgen()
Commit 05dfb26 added eatspace stripping to mcgen(). Move it to
cgen(), just in case somebody gets tempted to use cgen() directly
instead of via mcgen().

cgen() indents blank lines. No such lines get generated right now,
but fix it anyway.

We use triple-quoted strings for program text, like this:

'''
Program text
any number of lines
'''

Keeps the program text relatively readable, but puts an extra newline
at either end. mcgen() "fixes" that by dropping the first and last
line outright. Drop only the newlines.

This unmasks a bug in qapi-commands.py: four quotes instead of three.
Fix it up.

Output doesn't change

Backports commit 77e703b861d34bb2879f3e845482d5cf0a3a0ad1 from qemu
2018-02-19 16:04:37 -05:00
Daniel P. Berrange 767e900547
qom: Make enum string tables const-correct
The enum string table parameters in various QOM/QAPI methods
are declared 'const char *strings[]'. This results in const
warnings if passed a variable that was declared as

   static const char * const strings[] = { .... };

Add the extra const annotation to the parameters, since
neither the string elements, nor the array itself should
ever be modified.

Backports commit 2e4450ff432daef524cb3557fca68a3b7b5c7823 from qemu
2018-02-19 16:02:23 -05:00
Markus Armbruster 21b2c489af
qapi-types: Bury code dead since commit 6b5abc7
Backports commit e1d4210c3a50059a3889cedc44a8aa193fa63d7d from qemu
2018-02-19 15:58:09 -05:00
Peter Maydell 9a3972b6b2
scripts/qapi-types.py: Add dummy member to empty structs
Make sure that all generated C structs have at least one field; this
avoids potential issues with attempting to malloc space for
zero-length structs in C (g_malloc(sizeof struct) would return NULL).
It also avoids an incompatibility with C++ (where an empty struct is
size 1); that isn't important to us now but might be in future.

Generated empty structures look like this:
    struct Abort
    {
        char qapi_dummy_field_for_empty_struct;
    };

This silences clang warnings like:
./qapi-types.h:3752:1: warning: empty struct has size 0 in C, size 1 in C++ [-Wextern-c-compat]
struct Abort
^

Backports commit 83ecb22ba2c91a4674ae109595a8ed1da8de4d7a from qemu
2018-02-19 15:56:31 -05:00
Markus Armbruster 5efb546d6f
qapi-types: Split generate_fwd_builtin() off generate_fwd_struct()
Backports commit c5ecd7e18f912ab5e91f09b0333fb07567885d42 from qemu
2018-02-19 15:51:44 -05:00
Markus Armbruster e78c14f6e4
qapi-types: Drop unused members parameters
Backports commit ae0a7a109037160465f55f8bab06897f0a904def from qemu
2018-02-19 15:50:19 -05:00
Markus Armbruster 9ce13ce6a3
qapi-types: Don't filter out expressions with 'gen'
Useless, because it can only occur in commands, and we're not dealing
with commands here.

Backports commit 4f3568002393380558705397bda4cd5f224ffe29 from qemu
2018-02-19 15:48:52 -05:00
Markus Armbruster ed3da56d26
qapi: Catch and reject flat union branch of array type
Backports commit f9a1427361fe06ac67480d580412dc4ed6f5d03b from qemu
2018-02-19 15:48:12 -05:00
Markus Armbruster 52e7d76d23
qapi: Better separate the different kinds of helpers
Insert comments to separate sections dealing with parsing, semantic
analysis, code generation, and so forth.

Move helpers to their proper section.

Backports commit 00e4b285a31d19dcd88bd46729c9e09bfc9cc7fd from qemu
2018-02-19 15:47:21 -05:00
Markus Armbruster 0a8ab4fc40
qapi: Move exprs checking from parse_schema() to check_exprs()
To have expression semantic analysis in one place rather than two.

Backports commit 4d076d67c2c74662db092ecf4f99600b18209b2e from qemu
2018-02-19 15:45:24 -05:00
Markus Armbruster 72e6966bba
qapi: Fix to reject stray 't', 'f' and 'n'
Screwed up in commit e53188a.

Backports commit e565d934d21e3544b820cd03b88061e71ab644a0 from qemu
2018-02-19 15:41:38 -05:00
Markus Armbruster de88f40dfd
qapi: Simplify inclusion cycle detection
We maintain a stack of filenames in include_hist for convenient cycle
detection.

As error_path() demonstrates, the same information is readily
available in the expr_info, so just use that, and drop include_hist.

Backports commit a1366087270b312d94ff8c4031395a4218f160d4 from qemu
2018-02-19 15:40:44 -05:00
Markus Armbruster b387a62f73
qapi: Fix file name in error messages for included files
We print the name as it appears in the include expression. Tools
processing error messages want it relative to the working directory.
Make it so.

Backports commit 8608d2525186062099a38971c276752e7a38903a from qemu
2018-02-19 15:39:08 -05:00
Markus Armbruster a48f709cd8
qapi: Eliminate superfluous QAPISchema attribute input_dir
qapi: Improve a couple of confusing variable names

Backports commits 12c707944927b8aa42752198dcf419a0bafe5d33 and
54414047eca5bee7d5ba6e7af5fb251f8635896c from qemu
2018-02-19 15:37:52 -05:00
Markus Armbruster faffdb784a
qapi: Drop pointless flush() before close()
Backports commit 09896d3f48078a93e3d2dbd8ef86436b85ebda7c from qemu
2018-02-19 15:33:00 -05:00
Markus Armbruster 2c9ed3c379
qapi: Factor open_output(), close_output() out of generators
Backports commit 12f8e1b9ff57e99dafbb13f89cd5a99ad5c28527 from qemu
2018-02-19 15:32:28 -05:00
Markus Armbruster d77e0dd040
qapi: Turn generators' mandatory option -i into an argument
Mandatory option is silly, and the error handling is missing: the
programs crash when -i isn't supplied. Make it an argument, and check
it properly.

Backports commit 16d80f61814745bd3f5bb9f47ae3b00edf9e1e45 from qemu
2018-02-19 15:22:27 -05:00
Markus Armbruster dd67bbeb3b
qapi: Fix generators to report command line errors decently
Report to stderr, prefix with the program name. Also reject
extra arguments.

Backports commit b45409683e829770000a4560ed21e704f87df74c from qemu
2018-02-19 15:20:07 -05:00
Markus Armbruster 9415f6e863
qapi: Factor parse_command_line() out of the generators
Backports commit 2114f5a98d0d80774306279e1694de074ca86aa0 from qemu
2018-02-19 15:19:13 -05:00
Markus Armbruster f6a4f3033d
qapi: qapi-event.py option -b does nothing, drop it
Backports commit c70cef5bd48c7be603f75a7b5346db032a31b470 from qemu
2018-02-19 15:16:52 -05:00
Eric Blake 2dcd6722fa
qapi: Support downstream alternates
Enhance the testsuite to cover downstream alternates, including
whether the branch name or type is downstream. Update the
generator to mangle alternate names in the appropriate places.

Backports commit d1f07c86c05706facf950b0b0dba370f71fd5ef6 from qemu
2018-02-19 15:10:14 -05:00
Eric Blake 4292c61dbe
qapi: Support downstream flat unions
Enhance the testsuite to cover downstream flat unions, including
the base type, discriminator name and type, and branch name and
type. Update the generator to mangle the union names in the
appropriate places.

Backports commit 857af5f06c3fb097d1bb6bc8a23b9992aac99e75 from qemu
2018-02-19 15:06:36 -05:00
Eric Blake a2119bd210
qapi: Support downstream simple unions
Enhance the testsuite to cover downstream simple unions, including
when a union branch is a downstream name. Update the generator to
mangle the union names in the appropriate places.

Backports commit bb33729043ceda56b4068db13bdc17786ebd0ed0 from qemu
2018-02-19 15:05:10 -05:00
Eric Blake 2d14039f98
qapi: Support downstream structs
Enhance the testsuite to cover downstream structs, including struct
members and base structs. Update the generator to mangle the
struct names in the appropriate places.

Backports commit 83a02706bb1fd31c93eab755de543dfe228682d4 from qemu
2018-02-19 15:03:34 -05:00
Eric Blake 1a5b6a48d1
qapi: Support downstream enums
Enhance the testsuite to cover a downstream enum type and enum
string. Update the generator to mangle the enum name in the
appropriate places.

Backports commit fce384b8e5193e02421f6b2c2880f3684abcbdc0 from qemu
2018-02-19 15:01:08 -05:00
Eric Blake 2045cd0ada
qapi: Make c_type() consistently convert qapi names
Continuing the string of cleanups for supporting downstream names
containing '.', this patch focuses on ensuring c_type() can
handle a downstream name. This patch alone does not fix the
places where generator output should be calling this function
but was open-coding things instead, but it gets us a step closer.

In particular, the changes to c_list_type() and type_name() mean
that type_name(FOO) now handles the case when FOO contains '.',
'-', or is a ticklish identifier other than a builtin (builtins
are exempted because ['int'] must remain mapped to 'intList' and
not 'q_intList'). Meanwhile, ['unix'] now maps to 'q_unixList'
rather than 'unixList', to match the fact that 'unix' is ticklish;
however, our naming conventions state that complex types should
start with a capital, so no type name following conventions will
ever have the 'q_' prepended.

Likewise, changes to c_type() mean that c_type(FOO) properly
handles an enum or complex type FOO with '.' or '-' in the
name, or is a ticklish identifier (again, a ticklish identifier
as a type name violates conventions).

Backports commit c6405b54b7b09a876f2f2fba2aa6f8ac87189cb9 from qemu
2018-02-19 14:56:49 -05:00
Eric Blake 7ec0edc6c6
qapi: Tidy c_type() logic
c_type() is designed to be called on both string names and on
array designations, so 'name' is a bit misleading because it
operates on more than strings. Also, no caller ever passes
an empty string. Finally, + notation is a bit nicer to read
than '%s' % value for string concatenation.

Backports commit d557344628e32771f07e5b6a2a818ee3d8e7a65f from qemu
2018-02-19 14:53:56 -05:00
Markus Armbruster 5bc3d84705
qapi: Move camel_to_upper(), c_enum_const() to closely related code
Backports commit 849bc5382e42b3b9590c6a50ba30c2fd2450308c from qemu
2018-02-19 14:51:03 -05:00
Markus Armbruster e339979717
qapi: Simplify c_enum_const()
Backports commit 02e20c7e593363c564aae96e3c5bdc58630ce584 from qemu
2018-02-19 14:50:04 -05:00
Markus Armbruster b0adaeb172
qapi: Rename generate_enum_full_value() to c_enum_const()
Backports commit 7c81c61f9c2274f66ba947eafd9618d60da838a6 from qemu
2018-02-19 14:49:20 -05:00
Markus Armbruster 8c7bbc2dce
qapi: Rename _generate_enum_string() to camel_to_upper()
Backports commit fa6068a1e8ef3c878ac9ee2399bb01eeaf61c366 from qemu
2018-02-19 14:46:49 -05:00
Eric Blake f114c7b027
qapi: Rename identical c_fun()/c_var() into c_name()
Now that the two functions are identical, we only need one of them,
and we might as well give it a more descriptive name. Basically,
the function serves as the translation from a QAPI name into a
(portion of a) C identifier, without regards to whether it is a
variable or function name.

Backports commit 18df515ebbefa9f13474b128b8050d5fa346ea1e from qemu
2018-02-19 14:45:04 -05:00
Markus Armbruster baab1986a3
qapi: Fix C identifiers generated for names containing '.'
c_fun() maps '.' to '_', c_var() doesn't. Nothing prevents '.' in
QAPI names that get passed to c_var().

Which QAPI names get passed to c_fun(), to c_var(), or to both is not
obvious. Names of command parameters and struct type members get
passed to c_var().

c_var() strips a leading '*', but this cannot happen. c_fun()
doesn't.

Fix c_var() to work exactly like c_fun().

Perhaps they should be replaced by a single mapping function.

Backports commit 47299262de424af0cb69965d082e5e70b2314183 from qemu
2018-02-19 14:41:06 -05:00
Eric Blake 7a82e7ff73
qapi: Check for member name conflicts with a base class
Our type inheritance for both 'struct' and for flat 'union' merges
key/value pairs from the base class with those from the type in
question. Although the C code currently boxes things so that there
is a distinction between which member is referred to, the QMP wire
format does not allow passing a key more than once in a single
object. Besides, if we ever change the generated C code to not be
quite so boxy, we'd want to avoid duplicate member names there,
too.

Fix a testsuite entry added in an earlier patch, as well as adding
a couple more tests to ensure we have appropriate coverage. Ensure
that collisions are detected, regardless of whether there is a
difference in opinion on whether the member name is optional.

Backports commit ff55d72eaf9628e7d58e7b067b361cdbf789c9f4 from qemu
2018-02-19 14:38:46 -05:00
Eric Blake 90dfdc5278
qapi: Support (subset of) \u escapes in strings
The handling of \ inside QAPI strings was less than ideal, and
really only worked JSON's \/, \\, \", and our extension of \'
(an obvious extension, when you realize we use '' instead of ""
for strings). For other things, like '\n', it resulted in a
literal 'n' instead of a newline.

Of course, at the moment, we really have no use for escaped
characters, as QAPI has to map to C identifiers, and we currently
support ASCII only for that. But down the road, we may add
support for default values for string parameters to a command
or struct; if that happens, it would be nice to correctly support
all JSON escape sequences, such as \n or \uXXXX. This gets us
closer, by supporting Unicode escapes in the ASCII range.

Since JSON does not require \OCTAL or \xXX escapes, and our QMP
implementation does not understand them either, I intentionally
reject it here, but it would be an easy addition if we desired it.
Likewise, intentionally refusing the NUL byte means we don't have
to worry about C strings being shorter than the qapi input.

Backports commit a7f5966b297330f6492020019544ae87c45d699b from qemu
2018-02-19 14:36:54 -05:00
Eric Blake 937daf7d25
qapi: Drop dead visitor code related to nested structs
Now that we no longer have nested structs to visit, the use of
prefix strings is no longer required. Remove the code that is
no longer reachable.

Backports commit a82b982e2bddf7cd7cb490f83643e952e17d4523 from qemu
2018-02-19 14:35:55 -05:00
Eric Blake 8d2f349447
qapi: Drop support for inline nested types
A future patch will be using a 'name':{dictionary} entry in the
QAPI schema to specify a default value for an optional argument
(see previous commit messages for more details why); but existing
use of inline nested structs conflicts with that goal. Now that
all commands have been changed to avoid inline nested structs,
nuke support for them, and turn it into a hard error. Update the
testsuite to reflect tighter parsing rules.

Backports commit 6b5abc7df7ef9aadb3ff0eba6ccf4f1f0181e2e1 from qemu
2018-02-19 14:30:36 -05:00
Eric Blake 2d6d612c61
qapi: Forbid 'type' in schema
Referring to "type" as both a meta-type (built-in, enum, union,
alternate, or struct) and a specific type (the name that the
schema uses for declaring structs) is confusing. Finish up the
conversion to using "struct" in qapi schema by removing the hack
in the generator that allowed 'type'.

Backports commit 3e391d355644b2bff7c9f187759aadb46c6e051f from qemu
2018-02-19 14:23:21 -05:00