aboutsummaryrefslogtreecommitdiff
path: root/scripts/qapi/common.py
AgeCommit message (Collapse)Author
2019-03-05qapi: Fix array first used in a different moduleMarkus Armbruster
We generally put implicitly defined types in whatever module triggered their definition. This is wrong for array types, as the included test case demonstrates. Let's have a closer look at it. Type 'Status' is defined sub-sub-module.json. Array type ['Status'] occurs in main module qapi-schema-test.json and in include/sub-module.json. The main module's use is first, so the array type gets put into the main module. The generated C headers define StatusList in qapi-types.h. But include/qapi-types-sub-module.h uses it without including qapi-types.h. Oops. To fix that, put the array type into its element type's module. Now StatusList gets generated into qapi-types-sub-module.h, which all its users include. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20190301154051.23317-8-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
2019-03-05qapi: Fix code generation for sub-modules in other directoriesMarkus Armbruster
The #include directives to pull in sub-modules use file names relative to the main module. Works only when all modules are in the same directory, or the main module's output directory is in the compiler's include path. Use relative file names instead. The dummy variable we generate to avoid empty .o files has an invalid name for sub-modules in other directories. Fix that. Both messed up in commit 252dc3105fc "qapi: Generate separate .h, .c for each module". Escaped testing because tests/qapi-schema-test.json doesn't cover sub-modules in other directories, only tests/qapi-schema/include-relpath.json does, and we generate and compile C code only for the former, not the latter. Fold the latter into the former. This would have caught the mistakes fixed in this commit. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20190301154051.23317-5-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
2019-03-05qapi: Pass file name to QAPIGen constructor instead of methodsMarkus Armbruster
Not much of an improvement now, but the next commit will profit. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20190301154051.23317-4-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
2019-02-18qapi: Prepare for system modules other than 'builtin'Markus Armbruster
The next commit wants to generate qapi-emit-events.{c.h}. To enable that, extend QAPISchemaModularCVisitor to support additional "system modules", i.e. modules that don't correspond to a (user-defined) QAPI schema module. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20190214152251.2073-5-armbru@redhat.com>
2019-02-18qapi: Clean up modular built-in code generation a bitMarkus Armbruster
We neglect to call .visit_module() for the special module we use for built-ins. Harmless, but clean it up anyway. The tests/qapi-schema/*.out now show the built-in module as 'module None'. Subclasses of QAPISchemaModularCVisitor need to ._add_module() this special module to enable code generation for built-ins. When this hasn't been done, QAPISchemaModularCVisitor.visit_module() does nothing for the special module. That looks like built-ins could accidentally be generated into the wrong module when a subclass neglects to call ._add_module(). Can't happen, because built-ins are all visited before any other module. But that's non-obvious. Switch off code generation explicitly. Rename QAPISchemaModularCVisitor._begin_module() to ._begin_user_module(). New QAPISchemaModularCVisitor._is_builtin_module(), for clarity. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20190214152251.2073-4-armbru@redhat.com>
2018-12-18qapi: fix flat union on uncovered branches conditionalsMarc-André Lureau
Default branches variant should use the member conditional. This fixes compilation with --disable-replication. Fixes: 335d10cd8e2c3bb6067804b095aaf6371fc1983e Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20181217204046.14861-1-marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> [Long line wrapped] Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-12-14qapi: Add #if conditions to generated code membersMarc-André Lureau
Wrap generated enum and struct members and their supporting code with #if/#endif, using the .ifcond members added in the previous patches. We do enum and struct in a single patch because union tag enum and the associated variants tie them together, and dealing with that to split the patch doesn't seem worthwhile. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20181213123724.4866-18-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-12-13qapi: add 'if' to alternate membersMarc-André Lureau
Add 'if' key to alternate members: { 'alternate': 'TestIfAlternate', 'data': { 'alt': { 'type': 'TestStruct', 'if': 'COND' } } } Generated code is not changed by this patch but with "qapi: add #if conditions to generated code". Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20181213123724.4866-17-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-12-13qapi: add 'if' to union membersMarc-André Lureau
Add 'if' key to union members: { 'union': 'TestIfUnion', 'data': 'mem': { 'type': 'str', 'if': 'COND'} } The generated code remains unconditional for now. Later patches generate the conditionals. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20181213123724.4866-16-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-12-13qapi: Add 'if' to implicit struct membersMarc-André Lureau
The generated code is for now *unconditional*. Later patches generate the conditionals. Note that union discriminators may not have 'if' conditionals. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20181213123724.4866-14-marcandre.lureau@redhat.com> Message-Id: <20181213123724.4866-15-marcandre.lureau@redhat.com> [Patches squashed, commit message tweaked] Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-12-13qapi: add a dictionary form for TYPEMarc-André Lureau
Wherever a struct/union/alternate/command/event member with NAME: TYPE form is accepted, desugar it to a NAME: { 'type': TYPE } form. This will allow to add new member details, such as 'if' in the following patch to introduce conditionals, or 'default' for default values etc. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20181213123724.4866-13-marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-12-13qapi: add 'if' to enum membersMarc-André Lureau
QAPISchemaMember gains .ifcond for enum members: inherited classes, such as QAPISchemaObjectTypeMember, will thus have an ifcond member after this (those different types will also use the .ifcond to store the condition and generate conditional code in the following patches). The generated code remains unconditional for now. Later patches generate the conditionals. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20181213123724.4866-10-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-12-13qapi: add a dictionary form with 'name' key for enum membersMarc-André Lureau
Desugar the enum NAME form to { 'name': NAME }. This will allow to add new enum members, such as 'if' in the following patch. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20181213123724.4866-7-marcandre.lureau@redhat.com> Message-Id: <20181213123724.4866-8-marcandre.lureau@redhat.com> Message-Id: <20181213123724.4866-9-marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> [Harmless accidental move backed out, long line wrapped, patches squashed] Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-12-13qapi: improve reporting of unknown or missing keysMarc-André Lureau
Report the set of missing or unknown keys. And give a hint about the accepted keys. The error message for multiple meta type members (visible in tests/qapi-schema/double-type.err) is not improved. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20181213123724.4866-6-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-12-13qapi: factor out checking for keysMarc-André Lureau
Introduce a new helper function to check if the given keys are known, and if mandatory keys are present. The function will be reused in other places in the following code changes. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20181213123724.4866-5-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-12-13qapi: change enum visitor and gen_enum* to take QAPISchemaMemberMarc-André Lureau
This will allow to add and access more properties associated with enum values/members, like the associated 'if' condition. We may want to have a specialized type QAPISchemaEnumMember, for now this will do. Modify gen_enum() and gen_enum_lookup() for the same reason. Suggested-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20181213123724.4866-3-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-12-13qapi: Do not define enumeration value explicitlyMarc-André Lureau
The generated C enumeration types explicitly set the enumeration constants to 0, 1, 2, ... That's exactly what you get when you don't supply values. Drop the explicit values. No change now, but it will avoid gaps in the values when we later add support for 'if' conditions. Avoiding such gaps will save us the trouble of changing the ENUM_lookup[] tables to work without a sentinel. We'll have to take care to ensure the headers required by the 'if' conditions get always included before the generated QAPI code. Fortunately, our convention to include "qemu/osdep.h" first in any .c ensures that's the case for our CONFIG_FOO macros. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20181213123724.4866-2-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-12-13qapi: rename QAPISchemaEnumType.values to .membersMarc-André Lureau
Rename QAPISchemaEnumType.values and related variables to members. Makes sense ever since commit 93bda4dd4 changed .values from list of string to list of QAPISchemaMember. Obvious no-op. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20181208111606.8505-4-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-08-28qapi: Emit a blank line before dummy declarationMarkus Armbruster
We emit a dummy variable in each .c file "to shut up OSX toolchain warnings about empty .o files" (commit 252dc3105fc). Separate it from the code preceding it (if any) with a blank line. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20180828120736.32323-2-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
2018-08-28qapi: Fix build_params() for empty parameter listMarkus Armbruster
build_params() returns '' instead of 'void' when there are no parameters. Can't happen now, but the next commit will change that. Signed-off-by: Markus Armbruster <armbru@redhat.com> [peterx: compose the patch from email replies] Signed-off-by: Peter Xu <peterx@redhat.com> Message-Id: <20180815133747.25032-3-peterx@redhat.com>
2018-08-15qapi: Fix some pycodestyle-3 complaintsMarkus Armbruster
Fix the following issues: common.py:873:13: E129 visually indented line with same indent as next logical line common.py:1766:5: E741 ambiguous variable name 'l' common.py:1784:1: E305 expected 2 blank lines after class or function definition, found 1 common.py:1833:1: E305 expected 2 blank lines after class or function definition, found 1 common.py:1843:1: E305 expected 2 blank lines after class or function definition, found 1 visit.py:181:18: E127 continuation line over-indented for visual indent Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-Id: <20180621083551.775-1-armbru@redhat.com> [Fixup squashed in:] Message-ID: <871sd0nzw9.fsf@dusky.pond.sub.org> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
2018-07-03qapi: add #if/#endif helpersMarc-André Lureau
Add helpers to wrap generated code with #if/#endif lines. A later patch wants to use QAPIGen for generating C snippets rather than full C files with copyright headers etc. Splice in class QAPIGenCCode between QAPIGen and QAPIGenC. Add a 'with' statement context manager that will be used to wrap generator visitor methods. The manager will check if code was generated before adding #if/#endif lines on QAPIGenCSnippet objects. Used in the following patches. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20180703155648.11933-7-marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-07-03qapi: mcgen() shouldn't indent # linesMarc-André Lureau
Skip preprocessor lines when adding indentation, since that would likely result in invalid code. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20180703155648.11933-6-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-07-03qapi: add 'ifcond' to visitor methodsMarc-André Lureau
Modify the test visitor to check correct passing of values. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20180703155648.11933-5-marcandre.lureau@redhat.com> [Accidental change to roms/seabios dropped] Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-07-03qapi: leave the ifcond attribute undefined until check()Marc-André Lureau
We commonly initialize attributes to None in .init(), then set their real value in .check(). Accessing the attribute before .check() yields None. If we're lucky, the code that accesses the attribute prematurely chokes on None. It won't for .ifcond, because None is a legitimate value. Leave the ifcond attribute undefined until check(). Suggested-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20180703155648.11933-4-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-07-03qapi: pass 'if' condition into QAPISchemaEntity objectsMarc-André Lureau
Built-in objects remain unconditional. Explicitly defined objects use the condition specified in the schema. Implicitly defined objects inherit their condition from their users. For most of them, there is exactly one user, so the condition to use is obvious. The exception is wrapped types generated for simple union variants, which can be shared by any number of simple unions. The tight condition would be the disjunction of the conditions of these simple unions. For now, use the wrapped type's condition instead. Much simpler and good enough for now. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20180703155648.11933-3-marcandre.lureau@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-07-03qapi: add 'if' to top-level expressionsMarc-André Lureau
Accept 'if' key in top-level elements, accepted as string or list of string type. The following patches will modify the test visitor to check the value is correctly saved, and generate #if/#endif code (as a single #if/endif line or a series for a list). Example of 'if' key: { 'struct': 'TestIfStruct', 'data': { 'foo': 'int' }, 'if': 'defined(TEST_IF_STRUCT)' } The generated code is for now *unconditional*. Later patches generate the conditionals. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20180703155648.11933-2-marcandre.lureau@redhat.com> [Commit message and Documentation improved] Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-06-22qapi: Open files with encoding='utf-8'Markus Armbruster
Python 2 happily reads UTF-8 files in text mode, but Python 3 requires either UTF-8 locale or an explicit encoding passed to open(). Commit d4e5ec877ca fixed this by setting the en_US.UTF-8 locale. Falls apart when the locale isn't be available. Matthias Maier and Arfrever Frehtes Taifersar Arahesis proposed to use binary mode instead, with manual conversion from bytes to str. Works, but opening with an explicit encoding is simpler, so do that. Since Python 2's open() doesn't support the encoding parameter, we need to suppress it with a version check. Reported-by: Arfrever Frehtes Taifersar Arahesis <arfrever.fta@gmail.com> Reported-by: Matthias Maier <tamiko@43-1.org> Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20180618175958.29073-2-armbru@redhat.com> Reviewed-by: Eduardo Habkost <ehabkost@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
2018-06-22qapi: allow empty branches in flat unionsAnton Nefedov
It often happens that just a few discriminator values imply extra data in a flat union. Existing checks did not make possible to leave other values uncovered. Such cases had to be worked around by either stating a dummy (empty) type or introducing another (subset) discriminator enumeration. Both options create redundant entities in qapi files for little profit. With this patch it is not necessary anymore to add designated union fields for every possible value of a discriminator enumeration. Signed-off-by: Anton Nefedov <anton.nefedov@virtuozzo.com> Message-Id: <1529311206-76847-2-git-send-email-anton.nefedov@virtuozzo.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-06-08python: Remove scripts/ordereddict.pyEduardo Habkost
Python 2.7 (the minimum Python version we require) provides collections.OrderedDict on the standard library, so we don't need to carry our own implementation. Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> Message-Id: <20180608175252.25110-3-ehabkost@redhat.com> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
2018-05-30qapi: introduce new cmd option "allow-preconfig"Igor Mammedov
New option will be used to allow commands, which are prepared/need to run, during preconfig state. Other commands that should be able to run in preconfig state, should be amended to not expect machine in initialized state or deal with it. For compatibility reasons, commands that don't use new flag 'allow-preconfig' explicitly are not permitted to run in preconfig state but allowed in all other states like they used to be. Within this patch allow following commands in preconfig state: qmp_capabilities query-qmp-schema query-commands query-command-line-options query-status exit-preconfig to allow qmp connection, basic introspection and moving to the next state. PS: set-numa-node and query-hotpluggable-cpus will be enabled later in a separate patches. Signed-off-by: Igor Mammedov <imammedo@redhat.com> Message-Id: <1526057503-39287-1-git-send-email-imammedo@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> [ehabkost: Changed "since 2.13" to "since 3.0"] Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
2018-05-04qapi: add SysEmuTarget to "common.json"Laszlo Ersek
We'll soon need an enumeration type that lists all the softmmu targets that QEMU (the project) supports. Introduce @SysEmuTarget to "common.json". The enum constant @x86_64 doesn't match the QAPI convention of preferring hyphen ("-") over underscore ("_"). This is intentional; the @SysEmuTarget constants are supposed to produce QEMU executable names when stringified and appended to the "qemu-system-" prefix. Put differently, the replacement text of the TARGET_NAME preprocessor macro must be possible to look up in the list of (stringified) enum constants. Like other enum types, @SysEmuTarget too can be used for discriminator fields in unions. For the @i386 constant, a C-language union member called "i386" would be generated. On mingw build hosts, "i386" is a macro however. Add "i386" to "polluted_words" at once. Cc: "Daniel P. Berrange" <berrange@redhat.com> Cc: Eric Blake <eblake@redhat.com> Cc: Markus Armbruster <armbru@redhat.com> Signed-off-by: Laszlo Ersek <lersek@redhat.com> Message-Id: <20180427192852.15013-3-lersek@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2018-03-27qapi: restrict allow-oob value to be "true"Peter Xu
It was missed in the first version of OOB series. We should check this to make sure we throw the right error when fault value is passed in. Signed-off-by: Peter Xu <peterx@redhat.com> Message-Id: <20180326063901.27425-5-peterx@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Eric Blake <eblake@redhat.com>
2018-03-19qapi: introduce new cmd option "allow-oob"Peter Xu
Here "oob" stands for "Out-Of-Band". When "allow-oob" is set, it means the command allows out-of-band execution. The "oob" idea is proposed by Markus Armbruster in following thread: https://lists.gnu.org/archive/html/qemu-devel/2017-09/msg02057.html This new "allow-oob" boolean will be exposed by "query-qmp-schema" as well for command entries, so that QMP clients can know which commands can be used in out-of-band calls. For example the command "migrate" originally looks like: {"name": "migrate", "ret-type": "17", "meta-type": "command", "arg-type": "86"} And it'll be changed into: {"name": "migrate", "ret-type": "17", "allow-oob": false, "meta-type": "command", "arg-type": "86"} This patch only provides the QMP interface level changes. It does not contain the real out-of-band execution implementation yet. Suggested-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Fam Zheng <famz@redhat.com> Signed-off-by: Peter Xu <peterx@redhat.com> Message-Id: <20180309090006.10018-18-peterx@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> [eblake: rebase on introspection done by qlit] Signed-off-by: Eric Blake <eblake@redhat.com>
2018-03-02qapi: Move qapi-schema.json to qapi/, rename generated filesMarkus Armbruster
Move qapi-schema.json to qapi/, so it's next to its modules, and all files get generated to qapi/, not just the ones generated for modules. Consistently name the generated files qapi-MODULE.EXT: qmp-commands.[ch] become qapi-commands.[ch], qapi-event.[ch] become qapi-events.[ch], and qmp-introspect.[ch] become qapi-introspect.[ch]. This gets rid of the temporary hacks in scripts/qapi/commands.py, scripts/qapi/events.py, and scripts/qapi/common.py. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20180211093607.27351-28-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com> [eblake: Fix trailing dot in tpm.c, undo temporary hack for OSX toolchain] Signed-off-by: Eric Blake <eblake@redhat.com>
2018-03-02qapi: Generate separate .h, .c for each moduleMarkus Armbruster
Our qapi-schema.json is composed of modules connected by include directives, but the generated code is monolithic all the same: one qapi-types.h with all the types, one qapi-visit.h with all the visitors, and so forth. These monolithic headers get included all over the place. In my "build everything" tree, adding a QAPI type recompiles about 4800 out of 5100 objects. We wouldn't write such monolithic headers by hand. It stands to reason that we shouldn't generate them, either. Split up generated qapi-types.h to mirror the schema's modular structure: one header per module. Name the main module's header qapi-types.h, and sub-module D/B.json's header D/qapi-types-B.h. Mirror the schema's includes in the headers, so that qapi-types.h gets you everything exactly as before. If you need less, you can include one or more of the sub-module headers. To be exploited shortly. Split up qapi-types.c, qapi-visit.h, qapi-visit.c, qmp-commands.h, qmp-commands.c, qapi-event.h, qapi-event.c the same way. qmp-introspect.h, qmp-introspect.c and qapi.texi remain monolithic. The split of qmp-commands.c duplicates static helper function qmp_marshal_output_str() in qapi-commands-char.c and qapi-commands-misc.c. This happens when commands returning the same type occur in multiple modules. Not worth avoiding. Since I'm going to rename qapi-event.[ch] to qapi-events.[ch], and qmp-commands.[ch] to qapi-commands.[ch], name the shards that way already, to reduce churn. This requires temporary hacks in commands.py and events.py. Similarly, c_name() must temporarily be taught to munge '/' in common.py. They'll go away with the rename. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20180211093607.27351-23-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> [eblake: declare a dummy variable in each .c file, to shut up OSX toolchain warnings about empty .o files, including hacking c_name()] Signed-off-by: Eric Blake <eblake@redhat.com>
2018-03-02qapi/common: Fix guardname() for funny filenamesMarkus Armbruster
guardname() fails to return a valid C identifier for arguments containing anything but [A-Za-z0-9_.-']. Fix that. Don't bother protecting ticklish identifiers; header guards are all-caps, and no ticklish identifiers are. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20180211093607.27351-22-armbru@redhat.com> Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com> Signed-off-by: Eric Blake <eblake@redhat.com>
2018-03-02qapi/types qapi/visit: Generate built-in stuff into separate filesMarkus Armbruster
Linking code from multiple separate QAPI schemata into the same program is possible, but involves some weirdness around built-in types: * We generate code for built-in types into .c only with option --builtins. The user is responsible for generating code for exactly one QAPI schema per program with --builtins. * We generate code for built-in types into .h regardless of --builtins, but guarded by #ifndef QAPI_VISIT_BUILTIN. Because all copies of this code are exactly the same, including any combination of these headers works. Replace this contraption by something more conventional: generate code for built-in types into their very own files: qapi-builtin-types.c, qapi-builtin-visit.c, qapi-builtin-types.h, qapi-builtin-visit.h, but only with --builtins. Obey --output-dir, but ignore --prefix for them. Make qapi-types.h include qapi-builtin-types.h. With multiple schemata you now have multiple qapi-types.[ch], but only one qapi-builtin-types.[ch]. Same for qapi-visit.[ch] and qapi-builtin-visit.[ch]. Bonus: if all you need is built-in stuff, you can include a much smaller header. To be exploited shortly. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20180211093607.27351-21-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com> [eblake: fix octal constant for python 3] Signed-off-by: Eric Blake <eblake@redhat.com>
2018-03-02qapi: Make code-generating visitors use QAPIGen moreMarkus Armbruster
The use of QAPIGen is rather shallow so far: most of the output accumulation is not converted. Take the next step: convert output accumulation in the code-generating visitor classes. Helper functions outside these classes are not converted. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20180211093607.27351-20-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com> [eblake: rebase to earlier guardstart cleanup] Signed-off-by: Eric Blake <eblake@redhat.com>
2018-03-02qapi: Record 'include' directives in intermediate representationMarkus Armbruster
The include directive permits modular QAPI schemata, but the generated code is monolithic all the same. To permit generating modular code, the front end needs to pass more information on inclusions to the back ends. The commit before last added the necessary information to the parse tree. This commit adds it to the intermediate representation and its QAPISchemaVisitor. A later commit will use this to to generate modular code. New entity QAPISchemaInclude represents inclusions. Call new visitor method visit_include() for it, so visitors can see the sub-modules a module includes. Note that unlike other entities, QAPISchemaInclude has no name, and is therefore not added to entity_dict. New QAPISchemaEntity attribute @module names the entity's source file. Call new visitor method visit_module() when it changes during a visit, so visitors can keep track of the module being visited. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20180211093607.27351-18-armbru@redhat.com> [eblake: avoid accidental deletion of self._predefining] Signed-off-by: Eric Blake <eblake@redhat.com>
2018-03-02qapi: Generate in source orderMarkus Armbruster
The generators' conversion to visitors (merge commit 9e72681d16) changed the processing order of entities from source order to alphabetical order. The next commit needs source order, so change it back. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20180211093607.27351-17-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com> Signed-off-by: Eric Blake <eblake@redhat.com>
2018-03-02qapi: Record 'include' directives in parse treeMarkus Armbruster
The parse tree is a list of expressions. Except include expressions currently get replaced by the included file's parse tree. Instead of throwing away the include expression, keep it with the file name expanded so you don't have to track the including file's directory to make sense of it. A future commit will put this include expression to use. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20180211093607.27351-16-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> [eblake: fix check of expr after assignment] Signed-off-by: Eric Blake <eblake@redhat.com>
2018-03-02qapi: Concentrate QAPISchemaParser.exprs updates in .__init__()Markus Armbruster
Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20180211093607.27351-15-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com> Signed-off-by: Eric Blake <eblake@redhat.com>
2018-03-02qapi: Lift error reporting from QAPISchema.__init__() to callersMarkus Armbruster
Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20180211093607.27351-14-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com> Signed-off-by: Eric Blake <eblake@redhat.com>
2018-03-02qapi/common: Eliminate QAPISchema.exprsMarkus Armbruster
Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20180211093607.27351-13-armbru@redhat.com> Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com> Signed-off-by: Eric Blake <eblake@redhat.com>
2018-03-02qapi: Improve include file name reporting in error messagesMarkus Armbruster
Error messages print absolute file names of included files even if the user gave a relative one on the command line: $ PYTHONPATH=scripts python -B tests/qapi-schema/test-qapi.py tests/qapi-schema/include-cycle.json In file included from tests/qapi-schema/include-cycle.json:1: In file included from /work/armbru/qemu/tests/qapi-schema/include-cycle-b.json:1: /work/armbru/qemu/tests/qapi-schema/include-cycle-c.json:1: Inclusion loop for include-cycle.json Improve this to In file included from tests/qapi-schema/include-cycle.json:1: In file included from tests/qapi-schema/include-cycle-b.json:1: tests/qapi-schema/include-cycle-c.json:1: Inclusion loop for include-cycle.json The error message when an include file can't be opened prints the include directive's file name, which is relative to the including file. Change this to print the file name relative to the working directory. Visible in tests/qapi-schema/include-no-file.err. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20180211093607.27351-12-armbru@redhat.com> Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com> Signed-off-by: Eric Blake <eblake@redhat.com>
2018-03-02qapi: Touch generated files only when they changeMarkus Armbruster
A massive number of objects depends on QAPI-generated headers. In my "build everything" tree, it's roughly 4800 out of 5100. This is particularly annoying when only some of the generated files change, say for a doc fix. Improve qapi-gen.py to touch its output files only if they actually change. Rebuild time for a QAPI doc fix drops from many minutes to a few seconds. Rebuilds get faster for certain code changes, too. For instance, adding a simple QMP event now recompiles less than 200 instead of 4800 objects. But adding a QAPI type is as bad as ever; we've clearly got more work to do. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <20180211093607.27351-11-armbru@redhat.com> Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com> [eblake: fix octal constant for python3] Signed-off-by: Eric Blake <eblake@redhat.com>
2018-03-02qapi-gen: Convert from getopt to argparseMarkus Armbruster
argparse is nicer to use than getopt, and gives us --help almost for free. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20180211093607.27351-10-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> [eblake: Fix --output-dir editing accident] Signed-off-by: Eric Blake <eblake@redhat.com>
2018-03-02qapi-gen: New common driver for code and doc generatorsMarkus Armbruster
Whenever qapi-schema.json changes, we run six programs eleven times to update eleven files. Similar for qga/qapi-schema.json. This is silly. Replace the six programs by a single program that spits out all eleven files. The programs become modules in new Python package qapi, along with the helper library. This requires moving them to scripts/qapi/. While moving them, consistently drop executable mode bits. Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20180211093607.27351-9-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com> [eblake: move change to one-line 'blurb' earlier in series, mention mode bit change as intentional, update qapi-code-gen.txt to match actual generated events.c file] Signed-off-by: Eric Blake <eblake@redhat.com>