aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/devel/qapi-code-gen.rst10
-rw-r--r--scripts/qapi/parser.py73
-rw-r--r--tests/qapi-schema/doc-bad-indent.err2
-rw-r--r--tests/qapi-schema/doc-bad-indent.json3
-rw-r--r--tests/qapi-schema/doc-good.json3
-rw-r--r--tests/qapi-schema/doc-good.out3
6 files changed, 32 insertions, 62 deletions
diff --git a/docs/devel/qapi-code-gen.rst b/docs/devel/qapi-code-gen.rst
index 6386b58..875f893 100644
--- a/docs/devel/qapi-code-gen.rst
+++ b/docs/devel/qapi-code-gen.rst
@@ -1074,10 +1074,14 @@ Indentation matters. Bad example::
# @none: None (no memory side cache in this proximity domain,
# or cache associativity unknown)
+ # (since 5.0)
-The description is parsed as a definition list with term "None (no
-memory side cache in this proximity domain," and definition "or cache
-associativity unknown)".
+The last line's de-indent is wrong. The second and subsequent lines
+need to line up with each other, like this::
+
+ # @none: None (no memory side cache in this proximity domain,
+ # or cache associativity unknown)
+ # (since 5.0)
Section tags are case-sensitive and end with a colon. Good example::
diff --git a/scripts/qapi/parser.py b/scripts/qapi/parser.py
index a4ff9b6..285c9ff 100644
--- a/scripts/qapi/parser.py
+++ b/scripts/qapi/parser.py
@@ -474,17 +474,21 @@ class QAPIDoc:
self._parser = parser
# optional section name (argument/member or section name)
self.name = name
+ # section text without section name
self.text = ''
- # the expected indent level of the text of this section
- self._indent = indent
+ # indentation to strip (None means indeterminate)
+ self._indent = None if self.name else 0
def append(self, line: str) -> None:
- # Strip leading spaces corresponding to the expected indent level
- # Blank lines are always OK.
+ line = line.rstrip()
+
if line:
indent = must_match(r'\s*', line).end()
- if self._indent < 0:
- self._indent = indent
+ if self._indent is None:
+ # indeterminate indentation
+ if self.text != '':
+ # non-blank, non-first line determines indentation
+ self._indent = indent
elif indent < self._indent:
raise QAPIParseError(
self._parser,
@@ -492,7 +496,7 @@ class QAPIDoc:
self._indent)
line = line[self._indent:]
- self.text += line.rstrip() + '\n'
+ self.text += line + '\n'
class ArgSection(Section):
def __init__(self, parser: QAPISchemaParser,
@@ -622,22 +626,8 @@ class QAPIDoc:
"""
match = self._match_at_name_colon(line)
if match:
- # If line is "@arg: first line of description", find
- # the index of 'f', which is the indent we expect for any
- # following lines. We then remove the leading "@arg:"
- # from line and replace it with spaces so that 'f' has the
- # same index as it did in the original line and can be
- # handled the same way we will handle following lines.
- name = match.group(1)
- indent = match.end()
- line = line[indent:]
- if not line:
- # Line was just the "@arg:" header
- # The next non-blank line determines expected indent
- indent = -1
- else:
- line = ' ' * indent + line
- self._start_args_section(name, indent)
+ line = line[match.end():]
+ self._start_args_section(match.group(1), 0)
elif self._match_section_tag(line):
self._append_line = self._append_various_line
self._append_various_line(line)
@@ -657,22 +647,8 @@ class QAPIDoc:
def _append_features_line(self, line: str) -> None:
match = self._match_at_name_colon(line)
if match:
- # If line is "@arg: first line of description", find
- # the index of 'f', which is the indent we expect for any
- # following lines. We then remove the leading "@arg:"
- # from line and replace it with spaces so that 'f' has the
- # same index as it did in the original line and can be
- # handled the same way we will handle following lines.
- name = match.group(1)
- indent = match.end()
- line = line[indent:]
- if not line:
- # Line was just the "@arg:" header
- # The next non-blank line determines expected indent
- indent = -1
- else:
- line = ' ' * indent + line
- self._start_features_section(name, indent)
+ line = line[match.end():]
+ self._start_features_section(match.group(1), 0)
elif self._match_section_tag(line):
self._append_line = self._append_various_line
self._append_various_line(line)
@@ -704,21 +680,8 @@ class QAPIDoc:
% (match.group(1), self.sections[0].name))
match = self._match_section_tag(line)
if match:
- # If line is "Section: first line of description", find
- # the index of 'f', which is the indent we expect for any
- # following lines. We then remove the leading "Section:"
- # from line and replace it with spaces so that 'f' has the
- # same index as it did in the original line and can be
- # handled the same way we will handle following lines.
- indent = must_match(r'\S*:\s*', line).end()
- line = line[indent:]
- if not line:
- # Line was just the "Section:" header
- # The next non-blank line determines expected indent
- indent = 0
- else:
- line = ' ' * indent + line
- self._start_section(match.group(1), indent)
+ line = line[match.end():]
+ self._start_section(match.group(1), 0)
self._append_freeform(line)
@@ -754,7 +717,7 @@ class QAPIDoc:
self.sections.append(new_section)
def _switch_section(self, new_section: 'QAPIDoc.Section') -> None:
- text = self._section.text = self._section.text.strip()
+ text = self._section.text = self._section.text.strip('\n')
# Only the 'body' section is allowed to have an empty body.
# All other sections, including anonymous ones, must have text.
diff --git a/tests/qapi-schema/doc-bad-indent.err b/tests/qapi-schema/doc-bad-indent.err
index 6784453..3c9699a 100644
--- a/tests/qapi-schema/doc-bad-indent.err
+++ b/tests/qapi-schema/doc-bad-indent.err
@@ -1 +1 @@
-doc-bad-indent.json:6:1: unexpected de-indent (expected at least 4 spaces)
+doc-bad-indent.json:7:1: unexpected de-indent (expected at least 2 spaces)
diff --git a/tests/qapi-schema/doc-bad-indent.json b/tests/qapi-schema/doc-bad-indent.json
index edde8f2..3f22a27 100644
--- a/tests/qapi-schema/doc-bad-indent.json
+++ b/tests/qapi-schema/doc-bad-indent.json
@@ -3,6 +3,7 @@
##
# @foo:
# @a: line one
-# line two is wrongly indented
+# line two
+# line three is wrongly indented
##
{ 'command': 'foo', 'data': { 'a': 'int' } }
diff --git a/tests/qapi-schema/doc-good.json b/tests/qapi-schema/doc-good.json
index 34c3dcb..354dfdf 100644
--- a/tests/qapi-schema/doc-good.json
+++ b/tests/qapi-schema/doc-good.json
@@ -144,7 +144,8 @@
# description starts on a new line,
# indented
#
-# @arg2: the second argument
+# @arg2: description starts on the same line
+# remainder indented differently
#
# Features:
# @cmd-feat1: a feature
diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out
index 277371a..24d9ea9 100644
--- a/tests/qapi-schema/doc-good.out
+++ b/tests/qapi-schema/doc-good.out
@@ -161,7 +161,8 @@ doc symbol=cmd
description starts on a new line,
indented
arg=arg2
-the second argument
+description starts on the same line
+remainder indented differently
arg=arg3
feature=cmd-feat1