mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-10 02:54:58 -06:00
qapi: New classes QAPIGenC, QAPIGenH, QAPIGenDoc
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> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20180211093607.27351-6-armbru@redhat.com> Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com> [eblake: fix nits spotted by Michael] Signed-off-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
parent
d46eec4260
commit
47a6ea9aab
6 changed files with 117 additions and 98 deletions
|
@ -258,12 +258,10 @@ class QAPISchemaGenCommandVisitor(QAPISchemaVisitor):
|
||||||
|
|
||||||
blurb = ' * Schema-defined QAPI/QMP commands'
|
blurb = ' * Schema-defined QAPI/QMP commands'
|
||||||
|
|
||||||
(fdef, fdecl) = open_output(output_dir, do_c, do_h, prefix,
|
genc = QAPIGenC(blurb, __doc__)
|
||||||
'qmp-marshal.c', 'qmp-commands.h',
|
genh = QAPIGenH(blurb, __doc__)
|
||||||
blurb, __doc__)
|
|
||||||
|
|
||||||
fdef.write(mcgen('''
|
|
||||||
|
|
||||||
|
genc.add(mcgen('''
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
#include "qemu/module.h"
|
#include "qemu/module.h"
|
||||||
|
@ -280,7 +278,7 @@ fdef.write(mcgen('''
|
||||||
''',
|
''',
|
||||||
prefix=prefix))
|
prefix=prefix))
|
||||||
|
|
||||||
fdecl.write(mcgen('''
|
genh.add(mcgen('''
|
||||||
#include "%(prefix)sqapi-types.h"
|
#include "%(prefix)sqapi-types.h"
|
||||||
#include "qapi/qmp/dispatch.h"
|
#include "qapi/qmp/dispatch.h"
|
||||||
|
|
||||||
|
@ -291,7 +289,10 @@ void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds);
|
||||||
schema = QAPISchema(input_file)
|
schema = QAPISchema(input_file)
|
||||||
vis = QAPISchemaGenCommandVisitor()
|
vis = QAPISchemaGenCommandVisitor()
|
||||||
schema.visit(vis)
|
schema.visit(vis)
|
||||||
fdef.write(vis.defn)
|
genc.add(vis.defn)
|
||||||
fdecl.write(vis.decl)
|
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')
|
||||||
|
|
|
@ -174,11 +174,10 @@ class QAPISchemaGenEventVisitor(QAPISchemaVisitor):
|
||||||
|
|
||||||
blurb = ' * Schema-defined QAPI/QMP events'
|
blurb = ' * Schema-defined QAPI/QMP events'
|
||||||
|
|
||||||
(fdef, fdecl) = open_output(output_dir, do_c, do_h, prefix,
|
genc = QAPIGenC(blurb, __doc__)
|
||||||
'qapi-event.c', 'qapi-event.h',
|
genh = QAPIGenH(blurb, __doc__)
|
||||||
blurb, __doc__)
|
|
||||||
|
|
||||||
fdef.write(mcgen('''
|
genc.add(mcgen('''
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
#include "%(prefix)sqapi-event.h"
|
#include "%(prefix)sqapi-event.h"
|
||||||
|
@ -191,7 +190,7 @@ fdef.write(mcgen('''
|
||||||
''',
|
''',
|
||||||
prefix=prefix))
|
prefix=prefix))
|
||||||
|
|
||||||
fdecl.write(mcgen('''
|
genh.add(mcgen('''
|
||||||
#include "qapi/util.h"
|
#include "qapi/util.h"
|
||||||
#include "%(prefix)sqapi-types.h"
|
#include "%(prefix)sqapi-types.h"
|
||||||
|
|
||||||
|
@ -203,7 +202,10 @@ event_enum_name = c_name(prefix + 'QAPIEvent', protect=False)
|
||||||
schema = QAPISchema(input_file)
|
schema = QAPISchema(input_file)
|
||||||
vis = QAPISchemaGenEventVisitor()
|
vis = QAPISchemaGenEventVisitor()
|
||||||
schema.visit(vis)
|
schema.visit(vis)
|
||||||
fdef.write(vis.defn)
|
genc.add(vis.defn)
|
||||||
fdecl.write(vis.decl)
|
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')
|
||||||
|
|
|
@ -179,11 +179,10 @@ for o, a in opts:
|
||||||
|
|
||||||
blurb = ' * QAPI/QMP schema introspection'
|
blurb = ' * QAPI/QMP schema introspection'
|
||||||
|
|
||||||
(fdef, fdecl) = open_output(output_dir, do_c, do_h, prefix,
|
genc = QAPIGenC(blurb, __doc__)
|
||||||
'qmp-introspect.c', 'qmp-introspect.h',
|
genh = QAPIGenH(blurb, __doc__)
|
||||||
blurb, __doc__)
|
|
||||||
|
|
||||||
fdef.write(mcgen('''
|
genc.add(mcgen('''
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "%(prefix)sqmp-introspect.h"
|
#include "%(prefix)sqmp-introspect.h"
|
||||||
|
|
||||||
|
@ -193,7 +192,10 @@ fdef.write(mcgen('''
|
||||||
schema = QAPISchema(input_file)
|
schema = QAPISchema(input_file)
|
||||||
vis = QAPISchemaGenIntrospectVisitor(opt_unmask)
|
vis = QAPISchemaGenIntrospectVisitor(opt_unmask)
|
||||||
schema.visit(vis)
|
schema.visit(vis)
|
||||||
fdef.write(vis.defn)
|
genc.add(vis.defn)
|
||||||
fdecl.write(vis.decl)
|
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')
|
||||||
|
|
|
@ -180,7 +180,7 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
|
||||||
self.decl = ''
|
self.decl = ''
|
||||||
self.defn = ''
|
self.defn = ''
|
||||||
self._fwdecl = ''
|
self._fwdecl = ''
|
||||||
self._btin = guardstart('QAPI_TYPES_BUILTIN')
|
self._btin = '\n' + guardstart('QAPI_TYPES_BUILTIN')
|
||||||
|
|
||||||
def visit_end(self):
|
def visit_end(self):
|
||||||
self.decl = self._fwdecl + self.decl
|
self.decl = self._fwdecl + self.decl
|
||||||
|
@ -254,11 +254,10 @@ for o, a in opts:
|
||||||
|
|
||||||
blurb = ' * Schema-defined QAPI types'
|
blurb = ' * Schema-defined QAPI types'
|
||||||
|
|
||||||
(fdef, fdecl) = open_output(output_dir, do_c, do_h, prefix,
|
genc = QAPIGenC(blurb, __doc__)
|
||||||
'qapi-types.c', 'qapi-types.h',
|
genh = QAPIGenH(blurb, __doc__)
|
||||||
blurb, __doc__)
|
|
||||||
|
|
||||||
fdef.write(mcgen('''
|
genc.add(mcgen('''
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qapi/dealloc-visitor.h"
|
#include "qapi/dealloc-visitor.h"
|
||||||
#include "%(prefix)sqapi-types.h"
|
#include "%(prefix)sqapi-types.h"
|
||||||
|
@ -266,14 +265,17 @@ fdef.write(mcgen('''
|
||||||
''',
|
''',
|
||||||
prefix=prefix))
|
prefix=prefix))
|
||||||
|
|
||||||
fdecl.write(mcgen('''
|
genh.add(mcgen('''
|
||||||
#include "qapi/util.h"
|
#include "qapi/util.h"
|
||||||
'''))
|
'''))
|
||||||
|
|
||||||
schema = QAPISchema(input_file)
|
schema = QAPISchema(input_file)
|
||||||
vis = QAPISchemaGenTypeVisitor()
|
vis = QAPISchemaGenTypeVisitor()
|
||||||
schema.visit(vis)
|
schema.visit(vis)
|
||||||
fdef.write(vis.defn)
|
genc.add(vis.defn)
|
||||||
fdecl.write(vis.decl)
|
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')
|
||||||
|
|
|
@ -272,7 +272,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
|
||||||
def visit_begin(self, schema):
|
def visit_begin(self, schema):
|
||||||
self.decl = ''
|
self.decl = ''
|
||||||
self.defn = ''
|
self.defn = ''
|
||||||
self._btin = guardstart('QAPI_VISIT_BUILTIN')
|
self._btin = '\n' + guardstart('QAPI_VISIT_BUILTIN')
|
||||||
|
|
||||||
def visit_end(self):
|
def visit_end(self):
|
||||||
# To avoid header dependency hell, we always generate
|
# To avoid header dependency hell, we always generate
|
||||||
|
@ -337,11 +337,10 @@ for o, a in opts:
|
||||||
|
|
||||||
blurb = ' * Schema-defined QAPI visitors'
|
blurb = ' * Schema-defined QAPI visitors'
|
||||||
|
|
||||||
(fdef, fdecl) = open_output(output_dir, do_c, do_h, prefix,
|
genc = QAPIGenC(blurb, __doc__)
|
||||||
'qapi-visit.c', 'qapi-visit.h',
|
genh = QAPIGenH(blurb, __doc__)
|
||||||
blurb, __doc__)
|
|
||||||
|
|
||||||
fdef.write(mcgen('''
|
genc.add(mcgen('''
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
|
@ -350,7 +349,7 @@ fdef.write(mcgen('''
|
||||||
''',
|
''',
|
||||||
prefix=prefix))
|
prefix=prefix))
|
||||||
|
|
||||||
fdecl.write(mcgen('''
|
genh.add(mcgen('''
|
||||||
#include "qapi/visitor.h"
|
#include "qapi/visitor.h"
|
||||||
#include "%(prefix)sqapi-types.h"
|
#include "%(prefix)sqapi-types.h"
|
||||||
|
|
||||||
|
@ -360,7 +359,10 @@ fdecl.write(mcgen('''
|
||||||
schema = QAPISchema(input_file)
|
schema = QAPISchema(input_file)
|
||||||
vis = QAPISchemaGenVisitVisitor()
|
vis = QAPISchemaGenVisitVisitor()
|
||||||
schema.visit(vis)
|
schema.visit(vis)
|
||||||
fdef.write(vis.defn)
|
genc.add(vis.defn)
|
||||||
fdecl.write(vis.decl)
|
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')
|
||||||
|
|
106
scripts/qapi.py
106
scripts/qapi.py
|
@ -2,7 +2,7 @@
|
||||||
# QAPI helper library
|
# QAPI helper library
|
||||||
#
|
#
|
||||||
# Copyright IBM, Corp. 2011
|
# Copyright IBM, Corp. 2011
|
||||||
# Copyright (c) 2013-2016 Red Hat Inc.
|
# Copyright (c) 2013-2018 Red Hat Inc.
|
||||||
#
|
#
|
||||||
# Authors:
|
# Authors:
|
||||||
# Anthony Liguori <aliguori@us.ibm.com>
|
# Anthony Liguori <aliguori@us.ibm.com>
|
||||||
|
@ -22,10 +22,6 @@ try:
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
except:
|
except:
|
||||||
from ordereddict import OrderedDict
|
from ordereddict import OrderedDict
|
||||||
try:
|
|
||||||
from StringIO import StringIO
|
|
||||||
except ImportError:
|
|
||||||
from io import StringIO
|
|
||||||
|
|
||||||
builtin_types = {
|
builtin_types = {
|
||||||
'null': 'QTYPE_QNULL',
|
'null': 'QTYPE_QNULL',
|
||||||
|
@ -1831,7 +1827,6 @@ def guardname(filename):
|
||||||
|
|
||||||
def guardstart(name):
|
def guardstart(name):
|
||||||
return mcgen('''
|
return mcgen('''
|
||||||
|
|
||||||
#ifndef %(name)s
|
#ifndef %(name)s
|
||||||
#define %(name)s
|
#define %(name)s
|
||||||
|
|
||||||
|
@ -1843,7 +1838,6 @@ def guardend(name):
|
||||||
return mcgen('''
|
return mcgen('''
|
||||||
|
|
||||||
#endif /* %(name)s */
|
#endif /* %(name)s */
|
||||||
|
|
||||||
''',
|
''',
|
||||||
name=guardname(name))
|
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)
|
return (fname, output_dir, do_c, do_h, prefix, extra_opts)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Generate output files with boilerplate
|
# Accumulate and write output
|
||||||
#
|
#
|
||||||
|
|
||||||
|
class QAPIGen(object):
|
||||||
|
|
||||||
def open_output(output_dir, do_c, do_h, prefix, c_file, h_file, blurb, doc):
|
def __init__(self):
|
||||||
guard = guardname(prefix + h_file)
|
self._preamble = ''
|
||||||
c_file = output_dir + prefix + c_file
|
self._body = ''
|
||||||
h_file = output_dir + prefix + h_file
|
|
||||||
copyright = '\n * '.join(re.findall(r'^Copyright .*', doc, re.MULTILINE))
|
def preamble_add(self, text):
|
||||||
comment = mcgen('''/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
|
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 _top(self, fname):
|
||||||
|
return mcgen('''
|
||||||
|
/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
%(blurb)s
|
%(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()
|
|
||||||
|
|
||||||
fdef = maybe_open(do_c, c_file, 'w')
|
|
||||||
fdecl = maybe_open(do_h, h_file, 'w')
|
|
||||||
|
|
||||||
fdef.write(comment)
|
|
||||||
fdecl.write(comment)
|
|
||||||
fdecl.write(mcgen('''
|
|
||||||
#ifndef %(guard)s
|
|
||||||
#define %(guard)s
|
|
||||||
|
|
||||||
''',
|
|
||||||
guard=guard))
|
|
||||||
|
|
||||||
return (fdef, fdecl)
|
|
||||||
|
|
||||||
|
|
||||||
def close_output(fdef, fdecl):
|
class QAPIGenH(QAPIGenC):
|
||||||
fdecl.write(mcgen('''
|
|
||||||
|
|
||||||
#endif
|
def _top(self, fname):
|
||||||
'''))
|
return QAPIGenC._top(self, fname) + guardstart(fname)
|
||||||
fdecl.close()
|
|
||||||
fdef.close()
|
def _bottom(self, fname):
|
||||||
|
return guardend(fname)
|
||||||
|
|
||||||
|
|
||||||
|
class QAPIGenDoc(QAPIGen):
|
||||||
|
|
||||||
|
def _top(self, fname):
|
||||||
|
return (QAPIGen._top(self, fname)
|
||||||
|
+ '@c AUTOMATICALLY GENERATED, DO NOT MODIFY\n\n')
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue