diff options
author | Markus Armbruster <armbru@redhat.com> | 2018-02-26 13:48:58 -0600 |
---|---|---|
committer | Eric Blake <eblake@redhat.com> | 2018-03-02 13:14:09 -0600 |
commit | fb0bc835e56b894cbc7236294921e5393c786ad8 (patch) | |
tree | c96c6626054c20084fc9fe268fab187c0bed20bf /scripts | |
parent | 26df4e7fab06422b21e11d039c64243ca4003147 (diff) |
qapi-gen: New common driver for code and doc generators
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>
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/qapi-gen.py | 41 | ||||
-rw-r--r-- | scripts/qapi/__init__.py | 0 | ||||
-rw-r--r-- | scripts/qapi/commands.py (renamed from scripts/qapi-commands.py) | 19 | ||||
-rw-r--r-- | scripts/qapi/common.py (renamed from scripts/qapi.py) | 18 | ||||
-rw-r--r--[-rwxr-xr-x] | scripts/qapi/doc.py (renamed from scripts/qapi2texi.py) | 29 | ||||
-rw-r--r-- | scripts/qapi/events.py (renamed from scripts/qapi-event.py) | 19 | ||||
-rw-r--r-- | scripts/qapi/introspect.py (renamed from scripts/qapi-introspect.py) | 28 | ||||
-rw-r--r-- | scripts/qapi/types.py (renamed from scripts/qapi-types.py) | 30 | ||||
-rw-r--r-- | scripts/qapi/visit.py (renamed from scripts/qapi-visit.py) | 30 |
9 files changed, 73 insertions, 141 deletions
diff --git a/scripts/qapi-gen.py b/scripts/qapi-gen.py new file mode 100755 index 0000000000..2100ca1145 --- /dev/null +++ b/scripts/qapi-gen.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python +# QAPI generator +# +# This work is licensed under the terms of the GNU GPL, version 2 or later. +# See the COPYING file in the top-level directory. + +import sys +from qapi.common import parse_command_line, QAPISchema +from qapi.types import gen_types +from qapi.visit import gen_visit +from qapi.commands import gen_commands +from qapi.events import gen_events +from qapi.introspect import gen_introspect +from qapi.doc import gen_doc + + +def main(argv): + (input_file, output_dir, prefix, opts) = \ + parse_command_line('bu', ['builtins', 'unmask-non-abi-names']) + + opt_builtins = False + opt_unmask = False + + for o, a in opts: + if o in ('-b', '--builtins'): + opt_builtins = True + if o in ('-u', '--unmask-non-abi-names'): + opt_unmask = True + + schema = QAPISchema(input_file) + + gen_types(schema, output_dir, prefix, opt_builtins) + gen_visit(schema, output_dir, prefix, opt_builtins) + gen_commands(schema, output_dir, prefix) + gen_events(schema, output_dir, prefix) + gen_introspect(schema, output_dir, prefix, opt_unmask) + gen_doc(schema, output_dir, prefix) + + +if __name__ == '__main__': + main(sys.argv) diff --git a/scripts/qapi/__init__.py b/scripts/qapi/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/scripts/qapi/__init__.py diff --git a/scripts/qapi-commands.py b/scripts/qapi/commands.py index c20b22020e..a744611d58 100644 --- a/scripts/qapi-commands.py +++ b/scripts/qapi/commands.py @@ -13,7 +13,7 @@ This work is licensed under the terms of the GNU GPL, version 2. See the COPYING file in the top-level directory. """ -from qapi import * +from qapi.common import * def gen_command_decl(name, arg_type, boxed, ret_type): @@ -255,11 +255,8 @@ class QAPISchemaGenCommandVisitor(QAPISchemaVisitor): self._regy += gen_register_command(name, success_response) -def main(argv): - (input_file, output_dir, do_c, do_h, prefix, opts) = parse_command_line() - +def gen_commands(schema, output_dir, prefix): blurb = ' * Schema-defined QAPI/QMP commands' - genc = QAPIGenC(blurb, __doc__) genh = QAPIGenH(blurb, __doc__) @@ -288,17 +285,9 @@ void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds); ''', prefix=prefix, c_prefix=c_name(prefix, protect=False))) - schema = QAPISchema(input_file) vis = QAPISchemaGenCommandVisitor(prefix) schema.visit(vis) genc.add(vis.defn) genh.add(vis.decl) - - if do_c: - genc.write(output_dir, prefix + 'qmp-marshal.c') - if do_h: - genh.write(output_dir, prefix + 'qmp-commands.h') - - -if __name__ == '__main__': - main(sys.argv) + genc.write(output_dir, prefix + 'qmp-marshal.c') + genh.write(output_dir, prefix + 'qmp-commands.h') diff --git a/scripts/qapi.py b/scripts/qapi/common.py index f12cdddce6..3bc31a03ce 100644 --- a/scripts/qapi.py +++ b/scripts/qapi/common.py @@ -1932,17 +1932,15 @@ def parse_command_line(extra_options='', extra_long_options=[]): try: opts, args = getopt.gnu_getopt(sys.argv[1:], - 'chp:o:' + extra_options, - ['source', 'header', 'prefix=', - 'output-dir='] + extra_long_options) + 'p:o:' + extra_options, + ['prefix=', 'output-dir='] + + extra_long_options) except getopt.GetoptError as err: print("%s: %s" % (sys.argv[0], str(err)), file=sys.stderr) sys.exit(1) output_dir = '' prefix = '' - do_c = False - do_h = False extra_opts = [] for oa in opts: @@ -1956,23 +1954,15 @@ def parse_command_line(extra_options='', extra_long_options=[]): prefix = a elif o in ('-o', '--output-dir'): output_dir = a + '/' - elif o in ('-c', '--source'): - do_c = True - elif o in ('-h', '--header'): - do_h = True else: extra_opts.append(oa) - if not do_c and not do_h: - do_c = True - do_h = True - if len(args) != 1: print("%s: need exactly one argument" % sys.argv[0], file=sys.stderr) sys.exit(1) fname = args[0] - return (fname, output_dir, do_c, do_h, prefix, extra_opts) + return (fname, output_dir, prefix, extra_opts) # diff --git a/scripts/qapi2texi.py b/scripts/qapi/doc.py index 8a604d86a6..cc4d5a43fb 100755..100644 --- a/scripts/qapi2texi.py +++ b/scripts/qapi/doc.py @@ -4,11 +4,10 @@ # This work is licensed under the terms of the GNU LGPL, version 2+. # See the COPYING file in the top-level directory. """This script produces the documentation of a qapi schema in texinfo format""" + from __future__ import print_function import re -import sys - -import qapi +import qapi.common MSG_FMT = """ @deftypefn {type} {{}} {name} @@ -197,7 +196,7 @@ def texi_entity(doc, what, base=None, variants=None, + texi_sections(doc)) -class QAPISchemaGenDocVisitor(qapi.QAPISchemaVisitor): +class QAPISchemaGenDocVisitor(qapi.common.QAPISchemaVisitor): def __init__(self): self.out = None self.cur_doc = None @@ -272,20 +271,8 @@ def texi_schema(schema): return gen.out -def main(argv): - """Takes schema argument, prints result to stdout""" - if len(argv) != 2: - print("%s: need exactly 1 argument: SCHEMA" % argv[0], file=sys.stderr) - sys.exit(1) - - schema = qapi.QAPISchema(argv[1]) - if not qapi.doc_required: - print("%s: need pragma 'doc-required' " - "to generate documentation" % argv[0], file=sys.stderr) - sys.exit(1) - print('@c AUTOMATICALLY GENERATED, DO NOT MODIFY\n') - print(texi_schema(schema), end='') - - -if __name__ == '__main__': - main(sys.argv) +def gen_doc(schema, output_dir, prefix): + if qapi.common.doc_required: + gen = qapi.common.QAPIGenDoc() + gen.add(texi_schema(schema)) + gen.write(output_dir, prefix + 'qapi-doc.texi') diff --git a/scripts/qapi-event.py b/scripts/qapi/events.py index 1f8bf62c8b..b7dc82004f 100644 --- a/scripts/qapi-event.py +++ b/scripts/qapi/events.py @@ -12,7 +12,7 @@ This work is licensed under the terms of the GNU GPL, version 2. See the COPYING file in the top-level directory. """ -from qapi import * +from qapi.common import * def build_event_send_proto(name, arg_type, boxed): @@ -171,11 +171,8 @@ class QAPISchemaGenEventVisitor(QAPISchemaVisitor): self._event_names.append(name) -def main(argv): - (input_file, output_dir, do_c, do_h, prefix, dummy) = parse_command_line() - +def gen_events(schema, output_dir, prefix): blurb = ' * Schema-defined QAPI/QMP events' - genc = QAPIGenC(blurb, __doc__) genh = QAPIGenH(blurb, __doc__) @@ -199,17 +196,9 @@ def main(argv): ''', prefix=prefix)) - schema = QAPISchema(input_file) vis = QAPISchemaGenEventVisitor(prefix) schema.visit(vis) genc.add(vis.defn) genh.add(vis.decl) - - if do_c: - genc.write(output_dir, prefix + 'qapi-event.c') - if do_h: - genh.write(output_dir, prefix + 'qapi-event.h') - - -if __name__ == '__main__': - main(sys.argv) + genc.write(output_dir, prefix + 'qapi-event.c') + genh.write(output_dir, prefix + 'qapi-event.h') diff --git a/scripts/qapi-introspect.py b/scripts/qapi/introspect.py index cac219b4d8..1e4f065164 100644 --- a/scripts/qapi-introspect.py +++ b/scripts/qapi/introspect.py @@ -10,7 +10,7 @@ This work is licensed under the terms of the GNU GPL, version 2. See the COPYING file in the top-level directory. """ -from qapi import * +from qapi.common import * # Caveman's json.dumps() replacement (we're stuck at Python 2.4) @@ -168,20 +168,8 @@ const char %(c_name)s[] = %(c_string)s; self._gen_json(name, 'event', {'arg-type': self._use_type(arg_type)}) -def main(argv): - # Debugging aid: unmask QAPI schema's type names - # We normally mask them, because they're not QMP wire ABI - opt_unmask = False - - (input_file, output_dir, do_c, do_h, prefix, opts) = \ - parse_command_line('u', ['unmask-non-abi-names']) - - for o, a in opts: - if o in ('-u', '--unmask-non-abi-names'): - opt_unmask = True - +def gen_introspect(schema, output_dir, prefix, opt_unmask): blurb = ' * QAPI/QMP schema introspection' - genc = QAPIGenC(blurb, __doc__) genh = QAPIGenH(blurb, __doc__) @@ -192,17 +180,9 @@ def main(argv): ''', prefix=prefix)) - schema = QAPISchema(input_file) vis = QAPISchemaGenIntrospectVisitor(prefix, opt_unmask) schema.visit(vis) genc.add(vis.defn) genh.add(vis.decl) - - if do_c: - genc.write(output_dir, prefix + 'qmp-introspect.c') - if do_h: - genh.write(output_dir, prefix + 'qmp-introspect.h') - - -if __name__ == '__main__': - main(sys.argv) + genc.write(output_dir, prefix + 'qmp-introspect.c') + genh.write(output_dir, prefix + 'qmp-introspect.h') diff --git a/scripts/qapi-types.py b/scripts/qapi/types.py index 7d23544228..aa3c01e750 100644 --- a/scripts/qapi-types.py +++ b/scripts/qapi/types.py @@ -13,7 +13,7 @@ This work is licensed under the terms of the GNU GPL, version 2. # See the COPYING file in the top-level directory. """ -from qapi import * +from qapi.common import * # variants must be emitted before their container; track what has already @@ -241,22 +241,8 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor): self._gen_type_cleanup(name) -def main(argv): - # If you link code generated from multiple schemata, you want only one - # instance of the code for built-in types. Generate it only when - # opt_builtins, enabled by command line option -b. See also - # QAPISchemaGenTypeVisitor.visit_end(). - opt_builtins = False - - (input_file, output_dir, do_c, do_h, prefix, opts) = \ - parse_command_line('b', ['builtins']) - - for o, a in opts: - if o in ('-b', '--builtins'): - opt_builtins = True - +def gen_types(schema, output_dir, prefix, opt_builtins): blurb = ' * Schema-defined QAPI types' - genc = QAPIGenC(blurb, __doc__) genh = QAPIGenH(blurb, __doc__) @@ -272,17 +258,9 @@ def main(argv): #include "qapi/util.h" ''')) - schema = QAPISchema(input_file) vis = QAPISchemaGenTypeVisitor(opt_builtins) schema.visit(vis) genc.add(vis.defn) genh.add(vis.decl) - - if do_c: - genc.write(output_dir, prefix + 'qapi-types.c') - if do_h: - genh.write(output_dir, prefix + 'qapi-types.h') - - -if __name__ == '__main__': - main(sys.argv) + genc.write(output_dir, prefix + 'qapi-types.c') + genh.write(output_dir, prefix + 'qapi-types.h') diff --git a/scripts/qapi-visit.py b/scripts/qapi/visit.py index 3c23a9389d..3ed78165d7 100644 --- a/scripts/qapi-visit.py +++ b/scripts/qapi/visit.py @@ -13,7 +13,7 @@ This work is licensed under the terms of the GNU GPL, version 2. See the COPYING file in the top-level directory. """ -from qapi import * +from qapi.common import * def gen_visit_decl(name, scalar=False): @@ -324,22 +324,8 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor): self.defn += gen_visit_alternate(name, variants) -def main(argv): - # If you link code generated from multiple schemata, you want only one - # instance of the code for built-in types. Generate it only when - # opt_builtins, enabled by command line option -b. See also - # QAPISchemaGenVisitVisitor.visit_end(). - opt_builtins = False - - (input_file, output_dir, do_c, do_h, prefix, opts) = \ - parse_command_line('b', ['builtins']) - - for o, a in opts: - if o in ('-b', '--builtins'): - opt_builtins = True - +def gen_visit(schema, output_dir, prefix, opt_builtins): blurb = ' * Schema-defined QAPI visitors' - genc = QAPIGenC(blurb, __doc__) genh = QAPIGenH(blurb, __doc__) @@ -359,17 +345,9 @@ def main(argv): ''', prefix=prefix)) - schema = QAPISchema(input_file) vis = QAPISchemaGenVisitVisitor(opt_builtins) schema.visit(vis) genc.add(vis.defn) genh.add(vis.decl) - - if do_c: - genc.write(output_dir, prefix + 'qapi-visit.c') - if do_h: - genh.write(output_dir, prefix + 'qapi-visit.h') - - -if __name__ == '__main__': - main(sys.argv) + genc.write(output_dir, prefix + 'qapi-visit.c') + genh.write(output_dir, prefix + 'qapi-visit.h') |