aboutsummaryrefslogtreecommitdiff
path: root/scripts/qapi.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/qapi.py')
-rw-r--r--scripts/qapi.py107
1 files changed, 49 insertions, 58 deletions
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 62dc52ed6e..43a54bf40f 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -106,13 +106,10 @@ class QAPIDoc(object):
# optional section name (argument/member or section name)
self.name = name
# the list of lines for this section
- self.content = []
+ self.text = ''
def append(self, line):
- self.content.append(line)
-
- def __repr__(self):
- return '\n'.join(self.content).strip()
+ self.text += line.rstrip() + '\n'
class ArgSection(Section):
def __init__(self, name):
@@ -123,11 +120,11 @@ class QAPIDoc(object):
self.member = member
def __init__(self, parser, info):
- # self.parser is used to report errors with QAPIParseError. The
+ # self._parser is used to report errors with QAPIParseError. The
# resulting error position depends on the state of the parser.
# It happens to be the beginning of the comment. More or less
# servicable, but action at a distance.
- self.parser = parser
+ self._parser = parser
self.info = info
self.symbol = None
self.body = QAPIDoc.Section()
@@ -136,7 +133,7 @@ class QAPIDoc(object):
# a list of Section
self.sections = []
# the current section
- self.section = self.body
+ self._section = self.body
def has_section(self, name):
"""Return True if we have a section with this name."""
@@ -153,20 +150,20 @@ class QAPIDoc(object):
return
if line[0] != ' ':
- raise QAPIParseError(self.parser, "Missing space after #")
+ raise QAPIParseError(self._parser, "Missing space after #")
line = line[1:]
# FIXME not nice: things like '# @foo:' and '# @foo: ' aren't
# recognized, and get silently treated as ordinary text
if self.symbol:
self._append_symbol_line(line)
- elif not self.body.content and line.startswith('@'):
+ elif not self.body.text and line.startswith('@'):
if not line.endswith(':'):
- raise QAPIParseError(self.parser, "Line should end with :")
+ raise QAPIParseError(self._parser, "Line should end with :")
self.symbol = line[1:-1]
# FIXME invalid names other than the empty string aren't flagged
if not self.symbol:
- raise QAPIParseError(self.parser, "Invalid name")
+ raise QAPIParseError(self._parser, "Invalid name")
else:
self._append_freeform(line)
@@ -192,53 +189,48 @@ class QAPIDoc(object):
def _start_args_section(self, name):
# FIXME invalid names other than the empty string aren't flagged
if not name:
- raise QAPIParseError(self.parser, "Invalid parameter name")
+ raise QAPIParseError(self._parser, "Invalid parameter name")
if name in self.args:
- raise QAPIParseError(self.parser,
+ raise QAPIParseError(self._parser,
"'%s' parameter name duplicated" % name)
if self.sections:
- raise QAPIParseError(self.parser,
+ raise QAPIParseError(self._parser,
"'@%s:' can't follow '%s' section"
% (name, self.sections[0].name))
self._end_section()
- self.section = QAPIDoc.ArgSection(name)
- self.args[name] = self.section
+ self._section = QAPIDoc.ArgSection(name)
+ self.args[name] = self._section
- def _start_section(self, name=''):
+ def _start_section(self, name=None):
if name in ('Returns', 'Since') and self.has_section(name):
- raise QAPIParseError(self.parser,
+ raise QAPIParseError(self._parser,
"Duplicated '%s' section" % name)
self._end_section()
- self.section = QAPIDoc.Section(name)
- self.sections.append(self.section)
+ self._section = QAPIDoc.Section(name)
+ self.sections.append(self._section)
def _end_section(self):
- if self.section:
- contents = str(self.section)
- if self.section.name and (not contents or contents.isspace()):
- raise QAPIParseError(self.parser, "Empty doc section '%s'"
- % self.section.name)
- self.section = None
+ if self._section:
+ text = self._section.text = self._section.text.strip()
+ if self._section.name and (not text or text.isspace()):
+ raise QAPIParseError(self._parser, "Empty doc section '%s'"
+ % self._section.name)
+ self._section = None
def _append_freeform(self, line):
- in_arg = isinstance(self.section, QAPIDoc.ArgSection)
- if (in_arg and self.section.content
- and not self.section.content[-1]
+ in_arg = isinstance(self._section, QAPIDoc.ArgSection)
+ if (in_arg and self._section.text.endswith('\n\n')
and line and not line[0].isspace()):
self._start_section()
- if (in_arg or not self.section.name
- or not self.section.name.startswith('Example')):
+ if (in_arg or not self._section.name
+ or not self._section.name.startswith('Example')):
line = line.strip()
match = re.match(r'(@\S+:)', line)
if match:
- raise QAPIParseError(self.parser,
+ raise QAPIParseError(self._parser,
"'%s' not allowed in free-form documentation"
% match.group(1))
- # TODO Drop this once the dust has settled
- if (isinstance(self.section, QAPIDoc.ArgSection)
- and '#optional' in line):
- raise QAPISemError(self.info, "Please drop the #optional tag")
- self.section.append(line)
+ self._section.append(line)
def connect_member(self, member):
if member.name not in self.args:
@@ -265,8 +257,7 @@ class QAPISchemaParser(object):
def __init__(self, fp, previously_included=[], incl_info=None):
abs_fname = os.path.abspath(fp.name)
- fname = fp.name
- self.fname = fname
+ self.fname = fp.name
previously_included.append(abs_fname)
self.incl_info = incl_info
self.src = fp.read()
@@ -277,21 +268,21 @@ class QAPISchemaParser(object):
self.line_pos = 0
self.exprs = []
self.docs = []
- self.cur_doc = None
self.accept()
+ cur_doc = None
while self.tok is not None:
- info = {'file': fname, 'line': self.line,
+ info = {'file': self.fname, 'line': self.line,
'parent': self.incl_info}
if self.tok == '#':
- self.reject_expr_doc()
- self.cur_doc = self.get_doc(info)
- self.docs.append(self.cur_doc)
+ self.reject_expr_doc(cur_doc)
+ cur_doc = self.get_doc(info)
+ self.docs.append(cur_doc)
continue
expr = self.get_expr(False)
if 'include' in expr:
- self.reject_expr_doc()
+ self.reject_expr_doc(cur_doc)
if len(expr) != 1:
raise QAPISemError(info, "Invalid 'include' directive")
include = expr['include']
@@ -301,7 +292,7 @@ class QAPISchemaParser(object):
self._include(include, info, os.path.dirname(abs_fname),
previously_included)
elif "pragma" in expr:
- self.reject_expr_doc()
+ self.reject_expr_doc(cur_doc)
if len(expr) != 1:
raise QAPISemError(info, "Invalid 'pragma' directive")
pragma = expr['pragma']
@@ -313,22 +304,22 @@ class QAPISchemaParser(object):
else:
expr_elem = {'expr': expr,
'info': info}
- if self.cur_doc:
- if not self.cur_doc.symbol:
+ if cur_doc:
+ if not cur_doc.symbol:
raise QAPISemError(
- self.cur_doc.info,
- "Expression documentation required")
- expr_elem['doc'] = self.cur_doc
+ cur_doc.info, "Expression documentation required")
+ expr_elem['doc'] = cur_doc
self.exprs.append(expr_elem)
- self.cur_doc = None
- self.reject_expr_doc()
+ cur_doc = None
+ self.reject_expr_doc(cur_doc)
- def reject_expr_doc(self):
- if self.cur_doc and self.cur_doc.symbol:
+ @staticmethod
+ def reject_expr_doc(doc):
+ if doc and doc.symbol:
raise QAPISemError(
- self.cur_doc.info,
+ doc.info,
"Documentation for '%s' is not followed by the definition"
- % self.cur_doc.symbol)
+ % doc.symbol)
def _include(self, include, info, base_dir, previously_included):
incl_abs_fname = os.path.join(base_dir, include)