diff options
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/qapi/parser.py | 50 |
1 files changed, 35 insertions, 15 deletions
diff --git a/scripts/qapi/parser.py b/scripts/qapi/parser.py index 11707418fb..d8f76060b8 100644 --- a/scripts/qapi/parser.py +++ b/scripts/qapi/parser.py @@ -543,7 +543,7 @@ class QAPISchemaParser: line = self.get_doc_indented(doc) no_more_args = True elif match := re.match( - r'(Returns|Since|Notes?|Examples?|TODO): *', + r'(Returns|Errors|Since|Notes?|Examples?|TODO): *', line): # tagged section doc.new_tagged_section(self.info, match.group(1)) @@ -639,6 +639,11 @@ class QAPIDoc: # dicts mapping parameter/feature names to their description self.args: Dict[str, QAPIDoc.ArgSection] = {} self.features: Dict[str, QAPIDoc.ArgSection] = {} + # a command's "Returns" and "Errors" section + self.returns: Optional[QAPIDoc.Section] = None + self.errors: Optional[QAPIDoc.Section] = None + # "Since" section + self.since: Optional[QAPIDoc.Section] = None # sections other than .body, .args, .features self.sections: List[QAPIDoc.Section] = [] @@ -660,14 +665,22 @@ class QAPIDoc: self.all_sections.append(section) def new_tagged_section(self, info: QAPISourceInfo, tag: str) -> None: - if tag in ('Returns', 'Since'): - for section in self.all_sections: - if isinstance(section, self.ArgSection): - continue - if section.tag == tag: - raise QAPISemError( - info, "duplicated '%s' section" % tag) section = self.Section(info, tag) + if tag == 'Returns': + if self.returns: + raise QAPISemError( + info, "duplicated '%s' section" % tag) + self.returns = section + elif tag == 'Errors': + if self.errors: + raise QAPISemError( + info, "duplicated '%s' section" % tag) + self.errors = section + elif tag == 'Since': + if self.since: + raise QAPISemError( + info, "duplicated '%s' section" % tag) + self.since = section self.sections.append(section) self.all_sections.append(section) @@ -708,13 +721,20 @@ class QAPIDoc: self.features[feature.name].connect(feature) def check_expr(self, expr: QAPIExpression) -> None: - if 'command' not in expr: - sec = next((sec for sec in self.sections - if sec.tag == 'Returns'), - None) - if sec: - raise QAPISemError(sec.info, - "'Returns:' is only valid for commands") + if 'command' in expr: + if self.returns and 'returns' not in expr: + raise QAPISemError( + self.returns.info, + "'Returns' section, but command doesn't return anything") + else: + if self.returns: + raise QAPISemError( + self.returns.info, + "'Returns' section is only valid for commands") + if self.errors: + raise QAPISemError( + self.returns.info, + "'Errors' section is only valid for commands") def check(self) -> None: |