qapi: Factor QAPISchemaParser._include() out of .__init__()

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: <1489582656-31133-2-git-send-email-armbru@redhat.com>
This commit is contained in:
Markus Armbruster 2017-03-15 13:56:50 +01:00
parent f880cd6b6f
commit e04dea8872

View File

@ -268,34 +268,15 @@ class QAPISchemaParser(object):
continue continue
expr = self.get_expr(False) expr = self.get_expr(False)
if isinstance(expr, dict) and "include" in expr: if 'include' in expr:
if len(expr) != 1: if len(expr) != 1:
raise QAPISemError(info, "Invalid 'include' directive") raise QAPISemError(info, "Invalid 'include' directive")
include = expr["include"] include = expr["include"]
if not isinstance(include, str): if not isinstance(include, str):
raise QAPISemError(info, raise QAPISemError(info,
"Value of 'include' must be a string") "Value of 'include' must be a string")
incl_abs_fname = os.path.join(os.path.dirname(abs_fname), self._include(include, info, os.path.dirname(abs_fname),
include) previously_included)
# catch inclusion cycle
inf = info
while inf:
if incl_abs_fname == os.path.abspath(inf['file']):
raise QAPISemError(info, "Inclusion loop for %s"
% include)
inf = inf['parent']
# skip multiple include of the same file
if incl_abs_fname in previously_included:
continue
try:
fobj = open(incl_abs_fname, 'r')
except IOError as e:
raise QAPISemError(info, '%s: %s' % (e.strerror, include))
exprs_include = QAPISchemaParser(fobj, previously_included,
info)
self.exprs.extend(exprs_include.exprs)
self.docs.extend(exprs_include.docs)
else: else:
expr_elem = {'expr': expr, expr_elem = {'expr': expr,
'info': info} 'info': info}
@ -307,6 +288,26 @@ class QAPISchemaParser(object):
self.exprs.append(expr_elem) self.exprs.append(expr_elem)
def _include(self, include, info, base_dir, previously_included):
incl_abs_fname = os.path.join(base_dir, include)
# catch inclusion cycle
inf = info
while inf:
if incl_abs_fname == os.path.abspath(inf['file']):
raise QAPISemError(info, "Inclusion loop for %s" % include)
inf = inf['parent']
# skip multiple include of the same file
if incl_abs_fname in previously_included:
return
try:
fobj = open(incl_abs_fname, 'r')
except IOError as e:
raise QAPISemError(info, '%s: %s' % (e.strerror, include))
exprs_include = QAPISchemaParser(fobj, previously_included, info)
self.exprs.extend(exprs_include.exprs)
self.docs.extend(exprs_include.docs)
def accept(self, skip_comment=True): def accept(self, skip_comment=True):
while True: while True:
self.tok = self.src[self.cursor] self.tok = self.src[self.cursor]