mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-01-22 19:51:10 +00: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. Backports commit 47a6ea9aab1d857015684cda387ffba05a036721 from qemu
This commit is contained in:
parent
3fe150978c
commit
03c3b81d7a
|
@ -173,11 +173,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-common.h"
|
||||
#include "%(prefix)sqapi-event.h"
|
||||
#include "%(prefix)sqapi-visit.h"
|
||||
|
@ -187,20 +186,23 @@ fdef.write(mcgen('''
|
|||
#include "qapi/qmp-event.h"
|
||||
|
||||
''',
|
||||
prefix=prefix))
|
||||
prefix=prefix))
|
||||
|
||||
fdecl.write(mcgen('''
|
||||
genh.add(mcgen('''
|
||||
#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')
|
||||
|
|
|
@ -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,22 +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))
|
||||
|
||||
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')
|
||||
|
|
|
@ -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 "%(prefix)sqapi-visit.h"
|
||||
''',
|
||||
prefix=prefix))
|
||||
prefix=prefix))
|
||||
|
||||
fdecl.write(mcgen('''
|
||||
genh.add(mcgen('''
|
||||
#include "qapi/visitor.h"
|
||||
#include "qapi/qmp/qerror.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,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>
|
||||
|
@ -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',
|
||||
|
@ -1840,7 +1836,6 @@ def guardname(filename):
|
|||
|
||||
def guardstart(name):
|
||||
return mcgen('''
|
||||
|
||||
#ifndef %(name)s
|
||||
#define %(name)s
|
||||
|
||||
|
@ -1852,7 +1847,6 @@ def guardend(name):
|
|||
return mcgen('''
|
||||
|
||||
#endif /* %(name)s */
|
||||
|
||||
''',
|
||||
name=guardname(name))
|
||||
|
||||
|
@ -1985,17 +1979,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 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 __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 _top(self, fname):
|
||||
return mcgen('''
|
||||
/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
|
||||
|
||||
/*
|
||||
%(blurb)s
|
||||
|
@ -2007,40 +2037,19 @@ def open_output(output_dir, do_c, do_h, prefix, c_file, h_file, blurb, doc):
|
|||
*/
|
||||
|
||||
''',
|
||||
blurb=blurb, copyright=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)
|
||||
blurb=self._blurb, copyright=self._copyright)
|
||||
|
||||
|
||||
def close_output(fdef, fdecl):
|
||||
fdecl.write(mcgen('''
|
||||
class QAPIGenH(QAPIGenC):
|
||||
def _top(self, fname):
|
||||
return QAPIGenC._top(self, fname) + guardstart(fname)
|
||||
|
||||
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')
|
||||
|
||||
#endif
|
||||
'''))
|
||||
fdecl.close()
|
||||
fdef.close()
|
||||
|
|
Loading…
Reference in a new issue