qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PULL 05/30] qapi: New classes QAPIGenC, QAPIGenH, QAPIGenD


From: Eric Blake
Subject: [Qemu-devel] [PULL 05/30] qapi: New classes QAPIGenC, QAPIGenH, QAPIGenDoc
Date: Thu, 1 Mar 2018 13:42:20 -0600

From: Markus Armbruster <address@hidden>

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 <address@hidden>
Reviewed-by: Eric Blake <address@hidden>
Reviewed-by: Marc-André Lureau <address@hidden>
Message-Id: <address@hidden>
Reviewed-by: Michael Roth <address@hidden>
[eblake: fix nits spotted by Michael]
Signed-off-by: Eric Blake <address@hidden>
---
 scripts/qapi.py            | 98 +++++++++++++++++++++++++---------------------
 scripts/qapi-commands.py   | 23 +++++------
 scripts/qapi-event.py      | 22 ++++++-----
 scripts/qapi-introspect.py | 18 +++++----
 scripts/qapi-types.py      | 22 ++++++-----
 scripts/qapi-visit.py      | 24 ++++++------
 6 files changed, 113 insertions(+), 94 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index d2695cd8d60..f12cdddce64 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 <address@hidden>
@@ -22,10 +22,6 @@ try:
     from collections import OrderedDict
 except:
     from ordereddict import OrderedDict
-try:
-    from StringIO import StringIO
-except ImportError:
-    from io import StringIO

 builtin_types = {
     'null':     'QTYPE_QNULL',
@@ -1831,7 +1827,6 @@ def guardname(filename):

 def guardstart(name):
     return mcgen('''
-
 #ifndef %(name)s
 #define %(name)s

@@ -1843,7 +1838,6 @@ def guardend(name):
     return mcgen('''

 #endif /* %(name)s */
-
 ''',
                  name=guardname(name))

@@ -1980,17 +1974,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_add(self, text):
+        self._preamble += text
+
+    def add(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
+        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
@@ -2002,40 +2032,20 @@ def open_output(output_dir, do_c, do_h, prefix, c_file, 
h_file, blurb, doc):
  */

 ''',
-                    blurb=blurb, 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:
-            return 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)
+class QAPIGenDoc(QAPIGen):

-
-def close_output(fdef, fdecl):
-    fdecl.write(mcgen('''
-
-#endif
-'''))
-    fdecl.close()
-    fdef.close()
+    def _top(self, fname):
+        return (QAPIGen._top(self, fname)
+                + '@c AUTOMATICALLY GENERATED, DO NOT MODIFY\n\n')
diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index 114c5ad276b..8435a890baf 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -258,12 +258,10 @@ class QAPISchemaGenCommandVisitor(QAPISchemaVisitor):

 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.add(mcgen('''
 #include "qemu/osdep.h"
 #include "qemu-common.h"
 #include "qemu/module.h"
@@ -278,20 +276,23 @@ fdef.write(mcgen('''
 #include "%(prefix)sqmp-commands.h"

 ''',
-                 prefix=prefix))
+               prefix=prefix))

-fdecl.write(mcgen('''
+genh.add(mcgen('''
 #include "%(prefix)sqapi-types.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)
 vis = QAPISchemaGenCommandVisitor()
 schema.visit(vis)
-fdef.write(vis.defn)
-fdecl.write(vis.decl)
+genc.add(vis.defn)
+genh.add(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 9de5c6748e4..e063f6b8d13 100644
--- a/scripts/qapi-event.py
+++ b/scripts/qapi-event.py
@@ -174,11 +174,10 @@ class QAPISchemaGenEventVisitor(QAPISchemaVisitor):

 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.add(mcgen('''
 #include "qemu/osdep.h"
 #include "qemu-common.h"
 #include "%(prefix)sqapi-event.h"
@@ -189,21 +188,24 @@ fdef.write(mcgen('''
 #include "qapi/qmp-event.h"

 ''',
-                 prefix=prefix))
+               prefix=prefix))

-fdecl.write(mcgen('''
+genh.add(mcgen('''
 #include "qapi/util.h"
 #include "%(prefix)sqapi-types.h"

 ''',
-                  prefix=prefix))
+               prefix=prefix))

 event_enum_name = c_name(prefix + 'QAPIEvent', protect=False)

 schema = QAPISchema(input_file)
 vis = QAPISchemaGenEventVisitor()
 schema.visit(vis)
-fdef.write(vis.defn)
-fdecl.write(vis.decl)
+genc.add(vis.defn)
+genh.add(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 7a01a8f8f25..0638acda9ca 100644
--- a/scripts/qapi-introspect.py
+++ b/scripts/qapi-introspect.py
@@ -179,21 +179,23 @@ for o, a in opts:

 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.add(mcgen('''
 #include "qemu/osdep.h"
 #include "%(prefix)sqmp-introspect.h"

 ''',
-                 prefix=prefix))
+               prefix=prefix))

 schema = QAPISchema(input_file)
 vis = QAPISchemaGenIntrospectVisitor(opt_unmask)
 schema.visit(vis)
-fdef.write(vis.defn)
-fdecl.write(vis.decl)
+genc.add(vis.defn)
+genh.add(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 524d220ed75..1eb59b1dbb9 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
@@ -254,26 +254,28 @@ for o, a in opts:

 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.add(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.add(mcgen('''
 #include "qapi/util.h"
 '''))

 schema = QAPISchema(input_file)
 vis = QAPISchemaGenTypeVisitor()
 schema.visit(vis)
-fdef.write(vis.defn)
-fdecl.write(vis.decl)
+genc.add(vis.defn)
+genh.add(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 0e78cf3bbb5..51eeaa1fc22 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -272,7 +272,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
     def visit_begin(self, schema):
         self.decl = ''
         self.defn = ''
-        self._btin = guardstart('QAPI_VISIT_BUILTIN')
+        self._btin = '\n' + guardstart('QAPI_VISIT_BUILTIN')

     def visit_end(self):
         # To avoid header dependency hell, we always generate
@@ -337,30 +337,32 @@ for o, a in opts:

 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.add(mcgen('''
 #include "qemu/osdep.h"
 #include "qemu-common.h"
 #include "qapi/error.h"
 #include "qapi/qmp/qerror.h"
 #include "%(prefix)sqapi-visit.h"
 ''',
-                 prefix=prefix))
+               prefix=prefix))

-fdecl.write(mcgen('''
+genh.add(mcgen('''
 #include "qapi/visitor.h"
 #include "%(prefix)sqapi-types.h"

 ''',
-                  prefix=prefix))
+               prefix=prefix))

 schema = QAPISchema(input_file)
 vis = QAPISchemaGenVisitVisitor()
 schema.visit(vis)
-fdef.write(vis.defn)
-fdecl.write(vis.decl)
+genc.add(vis.defn)
+genh.add(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')
-- 
2.14.3




reply via email to

[Prev in Thread] Current Thread [Next in Thread]