[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH RFC 03/21] qapi: New classes QAPIGenC, QAPIGenH,
From: |
Marc-Andre Lureau |
Subject: |
Re: [Qemu-devel] [PATCH RFC 03/21] qapi: New classes QAPIGenC, QAPIGenH, QAPIGenDoc |
Date: |
Mon, 5 Feb 2018 14:44:47 +0100 |
Hi
On Fri, Feb 2, 2018 at 2:03 PM, Markus Armbruster <address@hidden> wrote:
> 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>
> ---
> 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 <address@hidden>
> @@ -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 ''
> +
Some methods appends, other return. That's a bit confusing. Why not
name them accordingly? add_preamble, add_body, get_top...?
> + 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
>
Reviewed-by: Marc-André Lureau <address@hidden>
- [Qemu-devel] [PATCH RFC 14/21] qapi: Generate in source order, (continued)
- [Qemu-devel] [PATCH RFC 03/21] qapi: New classes QAPIGenC, QAPIGenH, QAPIGenDoc, Markus Armbruster, 2018/02/02
- Re: [Qemu-devel] [PATCH RFC 03/21] qapi: New classes QAPIGenC, QAPIGenH, QAPIGenDoc, Eric Blake, 2018/02/02
- Re: [Qemu-devel] [PATCH RFC 03/21] qapi: New classes QAPIGenC, QAPIGenH, QAPIGenDoc, Markus Armbruster, 2018/02/03
- Re: [Qemu-devel] [PATCH RFC 03/21] qapi: New classes QAPIGenC, QAPIGenH, QAPIGenDoc, Eric Blake, 2018/02/05
- Re: [Qemu-devel] [PATCH RFC 03/21] qapi: New classes QAPIGenC, QAPIGenH, QAPIGenDoc, Markus Armbruster, 2018/02/06
Re: [Qemu-devel] [PATCH RFC 03/21] qapi: New classes QAPIGenC, QAPIGenH, QAPIGenDoc,
Marc-Andre Lureau <=
[Qemu-devel] [PATCH RFC 09/21] qapi: Don't absolutize include file name in error messages, Markus Armbruster, 2018/02/02
Re: [Qemu-devel] [PATCH RFC 09/21] qapi: Don't absolutize include file name in error messages, Marc-Andre Lureau, 2018/02/05
[Qemu-devel] [PATCH RFC 15/21] qapi: Record 'include' directives in intermediate representation, Markus Armbruster, 2018/02/02