From: Markus Armbruster <armbru@redhat.com>
To: qemu-devel@nongnu.org
Cc: marcandre.lureau@redhat.com, eblake@redhat.com,
mdroth@linux.vnet.ibm.com
Subject: [Qemu-devel] [PATCH RFC 03/21] qapi: New classes QAPIGenC, QAPIGenH, QAPIGenDoc
Date: Fri, 2 Feb 2018 14:03:18 +0100 [thread overview]
Message-ID: <20180202130336.24719-4-armbru@redhat.com> (raw)
In-Reply-To: <20180202130336.24719-1-armbru@redhat.com>
These classes encapsulate accumulating and writing output.
Convert C code generation to QAPIGenC and QAPIGenH. The conversion is
rather shallow: most of the output accumulation is not converted.
Left for later.
The indentation machinery uses a single global variable indent_level,
even though we generally interleave creation of a .c and its .h. It
should become instance variable of QAPIGenC. Also left for later.
Documentation generation isn't converted, and QAPIGenDoc isn't used.
This will change shortly.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
scripts/qapi-commands.py | 27 ++++++-------
scripts/qapi-event.py | 26 +++++++------
scripts/qapi-introspect.py | 22 ++++++-----
scripts/qapi-types.py | 26 +++++++------
scripts/qapi-visit.py | 26 +++++++------
scripts/qapi.py | 96 ++++++++++++++++++++++++++--------------------
6 files changed, 122 insertions(+), 101 deletions(-)
diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index a861ac52e7..4be7dbc482 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -260,12 +260,10 @@ blurb = '''
* Schema-defined QAPI/QMP commands
'''
-(fdef, fdecl) = open_output(output_dir, do_c, do_h, prefix,
- 'qmp-marshal.c', 'qmp-commands.h',
- blurb, __doc__)
-
-fdef.write(mcgen('''
+genc = QAPIGenC(blurb, __doc__)
+genh = QAPIGenH(blurb, __doc__)
+genc.body(mcgen('''
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/module.h"
@@ -279,21 +277,24 @@ fdef.write(mcgen('''
#include "%(prefix)sqmp-commands.h"
''',
- prefix=prefix))
+ prefix=prefix))
-fdecl.write(mcgen('''
+genh.body(mcgen('''
#include "%(prefix)sqapi-types.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/dispatch.h"
void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds);
''',
- prefix=prefix, c_prefix=c_name(prefix, protect=False)))
+ prefix=prefix, c_prefix=c_name(prefix, protect=False)))
schema = QAPISchema(input_file)
-gen = QAPISchemaGenCommandVisitor()
-schema.visit(gen)
-fdef.write(gen.defn)
-fdecl.write(gen.decl)
+vis = QAPISchemaGenCommandVisitor()
+schema.visit(vis)
+genc.body(vis.defn)
+genh.body(vis.decl)
-close_output(fdef, fdecl)
+if do_c:
+ genc.write(output_dir, prefix + 'qmp-marshal.c')
+if do_h:
+ genh.write(output_dir, prefix + 'qmp-commands.h')
diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py
index b1d611c5ea..da3de17c76 100644
--- a/scripts/qapi-event.py
+++ b/scripts/qapi-event.py
@@ -176,11 +176,10 @@ blurb = '''
* Schema-defined QAPI/QMP events
'''
-(fdef, fdecl) = open_output(output_dir, do_c, do_h, prefix,
- 'qapi-event.c', 'qapi-event.h',
- blurb, __doc__)
+genc = QAPIGenC(blurb, __doc__)
+genh = QAPIGenH(blurb, __doc__)
-fdef.write(mcgen('''
+genc.body(mcgen('''
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "%(prefix)sqapi-event.h"
@@ -190,22 +189,25 @@ fdef.write(mcgen('''
#include "qapi/qmp-event.h"
''',
- prefix=prefix))
+ prefix=prefix))
-fdecl.write(mcgen('''
+genh.body(mcgen('''
#include "qapi/util.h"
#include "qapi/qmp/qdict.h"
#include "%(prefix)sqapi-types.h"
''',
- prefix=prefix))
+ prefix=prefix))
event_enum_name = c_name(prefix + 'QAPIEvent', protect=False)
schema = QAPISchema(input_file)
-gen = QAPISchemaGenEventVisitor()
-schema.visit(gen)
-fdef.write(gen.defn)
-fdecl.write(gen.decl)
+vis = QAPISchemaGenEventVisitor()
+schema.visit(vis)
+genc.body(vis.defn)
+genh.body(vis.decl)
-close_output(fdef, fdecl)
+if do_c:
+ genc.write(output_dir, prefix + 'qapi-event.c')
+if do_h:
+ genh.write(output_dir, prefix + 'qapi-event.h')
diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
index bd9253a172..c654f8fa94 100644
--- a/scripts/qapi-introspect.py
+++ b/scripts/qapi-introspect.py
@@ -181,21 +181,23 @@ blurb = '''
* QAPI/QMP schema introspection
'''
-(fdef, fdecl) = open_output(output_dir, do_c, do_h, prefix,
- 'qmp-introspect.c', 'qmp-introspect.h',
- blurb, __doc__)
+genc = QAPIGenC(blurb, __doc__)
+genh = QAPIGenH(blurb, __doc__)
-fdef.write(mcgen('''
+genc.body(mcgen('''
#include "qemu/osdep.h"
#include "%(prefix)sqmp-introspect.h"
''',
- prefix=prefix))
+ prefix=prefix))
schema = QAPISchema(input_file)
-gen = QAPISchemaGenIntrospectVisitor(opt_unmask)
-schema.visit(gen)
-fdef.write(gen.defn)
-fdecl.write(gen.decl)
+vis = QAPISchemaGenIntrospectVisitor(opt_unmask)
+schema.visit(vis)
+genc.body(vis.defn)
+genh.body(vis.decl)
-close_output(fdef, fdecl)
+if do_c:
+ genc.write(output_dir, prefix + 'qmp-introspect.c')
+if do_h:
+ genh.write(output_dir, prefix + 'qmp-introspect.h')
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 1103dbda2d..97406b3368 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -180,7 +180,7 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
self.decl = ''
self.defn = ''
self._fwdecl = ''
- self._btin = guardstart('QAPI_TYPES_BUILTIN')
+ self._btin = '\n' + guardstart('QAPI_TYPES_BUILTIN')
def visit_end(self):
self.decl = self._fwdecl + self.decl
@@ -256,26 +256,28 @@ blurb = '''
* Schema-defined QAPI types
'''
-(fdef, fdecl) = open_output(output_dir, do_c, do_h, prefix,
- 'qapi-types.c', 'qapi-types.h',
- blurb, __doc__)
+genc = QAPIGenC(blurb, __doc__)
+genh = QAPIGenH(blurb, __doc__)
-fdef.write(mcgen('''
+genc.body(mcgen('''
#include "qemu/osdep.h"
#include "qapi/dealloc-visitor.h"
#include "%(prefix)sqapi-types.h"
#include "%(prefix)sqapi-visit.h"
''',
- prefix=prefix))
+ prefix=prefix))
-fdecl.write(mcgen('''
+genh.body(mcgen('''
#include "qapi/util.h"
'''))
schema = QAPISchema(input_file)
-gen = QAPISchemaGenTypeVisitor()
-schema.visit(gen)
-fdef.write(gen.defn)
-fdecl.write(gen.decl)
+vis = QAPISchemaGenTypeVisitor()
+schema.visit(vis)
+genc.body(vis.defn)
+genh.body(vis.decl)
-close_output(fdef, fdecl)
+if do_c:
+ genc.write(output_dir, prefix + 'qapi-types.c')
+if do_h:
+ genh.write(output_dir, prefix + 'qapi-types.h')
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 5231f89c36..d1b25daf0d 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -339,30 +339,32 @@ blurb = '''
* Schema-defined QAPI visitors
'''
-(fdef, fdecl) = open_output(output_dir, do_c, do_h, prefix,
- 'qapi-visit.c', 'qapi-visit.h',
- blurb, __doc__)
+genc = QAPIGenC(blurb, __doc__)
+genh = QAPIGenH(blurb, __doc__)
-fdef.write(mcgen('''
+genc.body(mcgen('''
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qapi/error.h"
#include "%(prefix)sqapi-visit.h"
''',
- prefix=prefix))
+ prefix=prefix))
-fdecl.write(mcgen('''
+genh.body(mcgen('''
#include "qapi/visitor.h"
#include "qapi/qmp/qerror.h"
#include "%(prefix)sqapi-types.h"
''',
- prefix=prefix))
+ prefix=prefix))
schema = QAPISchema(input_file)
-gen = QAPISchemaGenVisitVisitor()
-schema.visit(gen)
-fdef.write(gen.defn)
-fdecl.write(gen.decl)
+vis = QAPISchemaGenVisitVisitor()
+schema.visit(vis)
+genc.body(vis.defn)
+genh.body(vis.decl)
-close_output(fdef, fdecl)
+if do_c:
+ genc.write(output_dir, prefix + 'qapi-visit.c')
+if do_h:
+ genh.write(output_dir, prefix + 'qapi-visit.h')
diff --git a/scripts/qapi.py b/scripts/qapi.py
index d0816f7479..d73ef618e2 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -2,7 +2,7 @@
# QAPI helper library
#
# Copyright IBM, Corp. 2011
-# Copyright (c) 2013-2016 Red Hat Inc.
+# Copyright (c) 2013-2018 Red Hat Inc.
#
# Authors:
# Anthony Liguori <aliguori@us.ibm.com>
@@ -1820,7 +1820,6 @@ def guardname(filename):
def guardstart(name):
return mcgen('''
-
#ifndef %(name)s
#define %(name)s
@@ -1832,7 +1831,6 @@ def guardend(name):
return mcgen('''
#endif /* %(name)s */
-
''',
name=guardname(name))
@@ -1970,17 +1968,53 @@ def parse_command_line(extra_options='', extra_long_options=[]):
return (fname, output_dir, do_c, do_h, prefix, extra_opts)
+
#
-# Generate output files with boilerplate
+# Accumulate and write output
#
+class QAPIGen(object):
+
+ def __init__(self):
+ self._preamble = ''
+ self._body = ''
+
+ def preamble(self, text):
+ self._preamble += text
+
+ def body(self, text):
+ self._body += text
+
+ def top(self, fname):
+ return ''
+
+ def bottom(self, fname):
+ return ''
+
+ def write(self, output_dir, fname):
+ if output_dir:
+ try:
+ os.makedirs(output_dir)
+ except os.error as e:
+ if e.errno != errno.EEXIST:
+ raise
+ f = open(os.path.join(output_dir, fname), 'w')
+ f.write(self.top(fname) + self._preamble + self._body
+ + self.bottom(fname))
+ f.close()
+
+
+class QAPIGenC(QAPIGen):
+
+ def __init__(self, blurb, pydoc):
+ QAPIGen.__init__(self)
+ self._blurb = blurb.strip('\n')
+ self._copyright = '\n * '.join(re.findall(r'^Copyright .*', pydoc,
+ re.MULTILINE))
-def open_output(output_dir, do_c, do_h, prefix, c_file, h_file, blurb, doc):
- guard = guardname(prefix + h_file)
- c_file = output_dir + prefix + c_file
- h_file = output_dir + prefix + h_file
- copyright = '\n * '.join(re.findall(r'^Copyright .*', doc, re.MULTILINE))
- comment = mcgen('''/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
+ def top(self, fname):
+ return mcgen('''
+/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
/*
%(blurb)s
@@ -1992,41 +2026,19 @@ def open_output(output_dir, do_c, do_h, prefix, c_file, h_file, blurb, doc):
*/
''',
- blurb=blurb.strip('\n'), copyright=copyright)
+ blurb=self._blurb, copyright=self._copyright)
- if output_dir:
- try:
- os.makedirs(output_dir)
- except os.error as e:
- if e.errno != errno.EEXIST:
- raise
- def maybe_open(really, name, opt):
- if really:
- return open(name, opt)
- else:
- import StringIO
- return StringIO.StringIO()
+class QAPIGenH(QAPIGenC):
- fdef = maybe_open(do_c, c_file, 'w')
- fdecl = maybe_open(do_h, h_file, 'w')
+ def top(self, fname):
+ return QAPIGenC.top(self, fname) + guardstart(fname)
- fdef.write(comment)
- fdecl.write(comment)
- fdecl.write(mcgen('''
-#ifndef %(guard)s
-#define %(guard)s
+ def bottom(self, fname):
+ return guardend(fname)
-''',
- guard=guard))
- return (fdef, fdecl)
-
-
-def close_output(fdef, fdecl):
- fdecl.write(mcgen('''
-
-#endif
-'''))
- fdecl.close()
- fdef.close()
+class QAPIGenDoc(QAPIGen):
+ def top(self, fname):
+ return (QAPIGen.top(self, fname)
+ + '@c AUTOMATICALLY GENERATED, DO NOT MODIFY\n\n')
--
2.13.6
next prev parent reply other threads:[~2018-02-02 15:34 UTC|newest]
Thread overview: 87+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-02-02 13:03 [Qemu-devel] [PATCH RFC 00/21] Modularize generated QAPI code Markus Armbruster
2018-02-02 13:03 ` [Qemu-devel] [PATCH RFC 01/21] qapi: Streamline boilerplate comment generation Markus Armbruster
2018-02-02 15:08 ` Eric Blake
2018-02-03 8:45 ` Markus Armbruster
2018-02-05 13:44 ` Marc-Andre Lureau
2018-02-02 13:03 ` [Qemu-devel] [PATCH RFC 02/21] qapi: Generate up-to-date copyright notice Markus Armbruster
2018-02-02 15:47 ` Eric Blake
2018-02-03 8:48 ` Markus Armbruster
2018-02-05 13:44 ` Marc-Andre Lureau
2018-02-05 15:28 ` Markus Armbruster
2018-02-05 15:45 ` Eric Blake
2018-02-02 13:03 ` Markus Armbruster [this message]
2018-02-02 15:59 ` [Qemu-devel] [PATCH RFC 03/21] qapi: New classes QAPIGenC, QAPIGenH, QAPIGenDoc Eric Blake
2018-02-03 8:49 ` Markus Armbruster
2018-02-05 15:46 ` Eric Blake
2018-02-06 7:28 ` Markus Armbruster
2018-02-05 13:44 ` Marc-Andre Lureau
2018-02-05 15:34 ` Markus Armbruster
2018-02-02 13:03 ` [Qemu-devel] [PATCH RFC 04/21] qapi: Reduce use of global variables in generators some Markus Armbruster
2018-02-02 16:03 ` Eric Blake
2018-02-05 13:44 ` Marc-Andre Lureau
2018-02-02 13:03 ` [Qemu-devel] [PATCH RFC 05/21] qapi: Turn generators into modules Markus Armbruster
2018-02-02 16:47 ` Eric Blake
2018-02-05 13:44 ` Marc-Andre Lureau
2018-02-02 13:03 ` [Qemu-devel] [PATCH RFC 06/21] qapi-gen: New common driver for code and doc generators Markus Armbruster
2018-02-02 19:27 ` Eric Blake
2018-02-03 9:03 ` Markus Armbruster
2018-02-05 15:52 ` Eric Blake
2018-02-06 7:45 ` Markus Armbruster
2018-02-06 14:56 ` Eric Blake
2018-02-05 13:44 ` Marc-Andre Lureau
2018-02-05 15:36 ` Markus Armbruster
2018-02-08 9:55 ` Markus Armbruster
2018-02-02 13:03 ` [Qemu-devel] [PATCH RFC 07/21] qapi: Move parse_command_line() next to its only use Markus Armbruster
2018-02-02 19:29 ` Eric Blake
2018-02-05 13:45 ` Marc-Andre Lureau
2018-02-02 13:03 ` [Qemu-devel] [PATCH RFC 08/21] qapi: Touch generated files only when they change Markus Armbruster
2018-02-02 19:42 ` Eric Blake
2018-02-03 9:05 ` Markus Armbruster
2018-02-02 13:03 ` [Qemu-devel] [PATCH RFC 09/21] qapi: Don't absolutize include file name in error messages Markus Armbruster
2018-02-02 20:22 ` Eric Blake
2018-02-03 9:08 ` Markus Armbruster
2018-02-05 15:55 ` Eric Blake
2018-02-06 7:49 ` Markus Armbruster
2018-02-06 15:06 ` Eric Blake
2018-02-05 13:46 ` Marc-Andre Lureau
2018-02-02 13:03 ` [Qemu-devel] [PATCH RFC 10/21] qapi/common: Eliminate QAPISchema.exprs Markus Armbruster
2018-02-02 22:02 ` Eric Blake
2018-02-05 13:45 ` Marc-Andre Lureau
2018-02-02 13:03 ` [Qemu-devel] [PATCH RFC 11/21] qapi: Lift error reporting from QAPISchema.__init__() to callers Markus Armbruster
2018-02-05 13:45 ` Marc-Andre Lureau
2018-02-02 13:03 ` [Qemu-devel] [PATCH RFC 12/21] qapi: Concentrate QAPISchemaParser.exprs updates in .__init__() Markus Armbruster
2018-02-05 13:45 ` Marc-Andre Lureau
2018-02-05 14:26 ` Markus Armbruster
2018-02-02 13:03 ` [Qemu-devel] [PATCH RFC 13/21] qapi: Record 'include' directives in parse tree Markus Armbruster
2018-02-05 13:45 ` Marc-Andre Lureau
2018-02-02 13:03 ` [Qemu-devel] [PATCH RFC 14/21] qapi: Generate in source order Markus Armbruster
2018-02-05 13:45 ` Marc-Andre Lureau
2018-02-05 14:33 ` Markus Armbruster
2018-02-05 14:40 ` Marc-Andre Lureau
2018-02-06 10:33 ` Markus Armbruster
2018-02-02 13:03 ` [Qemu-devel] [PATCH RFC 15/21] qapi: Record 'include' directives in intermediate representation Markus Armbruster
2018-02-05 13:45 ` Marc-Andre Lureau
2018-02-02 13:03 ` [Qemu-devel] [PATCH RFC 16/21] qapi/types qapi/visit: Make visitors use QAPIGen more Markus Armbruster
2018-02-05 13:46 ` Marc-Andre Lureau
2018-02-02 13:03 ` [Qemu-devel] [PATCH RFC 17/21] qapi/types qapi/visit: Generate built-in stuff into separate files Markus Armbruster
2018-02-05 13:46 ` Marc-Andre Lureau
2018-02-06 20:54 ` Eric Blake
2018-02-02 13:03 ` [Qemu-devel] [PATCH RFC 18/21] qapi/common: Fix guardname() for funny filenames Markus Armbruster
2018-02-05 13:47 ` Marc-Andre Lureau
2018-02-06 21:00 ` Eric Blake
2018-02-02 13:03 ` [Qemu-devel] [PATCH RFC 19/21] qapi/types: Generate separate .h, .c for each module Markus Armbruster
2018-02-05 13:58 ` Marc-Andre Lureau
2018-02-02 13:03 ` [Qemu-devel] [PATCH RFC 20/21] Include less of qapi-types.h Markus Armbruster
2018-02-05 13:46 ` Marc-Andre Lureau
2018-02-05 14:53 ` Markus Armbruster
2018-02-02 13:03 ` [Qemu-devel] [PATCH RFC 21/21] qapi: Empty out qapi-schema.json Markus Armbruster
2018-02-05 13:45 ` Marc-Andre Lureau
2018-02-02 14:52 ` [Qemu-devel] [PATCH RFC 00/21] Modularize generated QAPI code Markus Armbruster
2018-02-02 16:44 ` Daniel P. Berrangé
2018-02-03 9:18 ` Markus Armbruster
2018-02-02 18:36 ` no-reply
2018-02-02 19:33 ` no-reply
2018-02-02 20:11 ` no-reply
2018-02-02 21:13 ` no-reply
2018-02-02 22:14 ` no-reply
2018-02-03 11:30 ` Markus Armbruster
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180202130336.24719-4-armbru@redhat.com \
--to=armbru@redhat.com \
--cc=eblake@redhat.com \
--cc=marcandre.lureau@redhat.com \
--cc=mdroth@linux.vnet.ibm.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).