From nobody Mon Feb 9 22:20:24 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1683619494; cv=none; d=zohomail.com; s=zohoarc; b=fELgaCnsCJimXcgSlu7IDA5CUcuQPZ1p/Pojb2xEU2buBStXD0CepT9Y3jimg3R2W4xpYtdPa1azvSCcQKjoboTFVxi1xXYAFeDcWKTLK+LYyy+GiRZgfTJ43pLtSLS4Rh1wX2Tn88sGEVuVT0Y9S12uBQqXU3ilYWngqK1Sax8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1683619494; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=BNCfKT61deeM62mksJwv6S1TyaJ5AQ1h8o0X7+3Q+Ig=; b=i3HyJ8OxIV55UBx2VxzYWOOT0KJIH8hh/LK+A+oJMAv4jJn58TbAZPKh1I78xvdkLWX3dcygQkJ6afSRsk48mYDkLQ1SDil7fl0EECJt9xcF145DA57AHIfW3Mi6bJimLgW5zpmlCefkoFGN59EJ8EfJwfyeORshaAZXbbSYHIA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1683619494670485.99491146380774; Tue, 9 May 2023 01:04:54 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pwIGw-00008u-5z; Tue, 09 May 2023 04:00:34 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pwIGn-0008Ua-M1 for qemu-devel@nongnu.org; Tue, 09 May 2023 04:00:27 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pwIGl-0008V4-UX for qemu-devel@nongnu.org; Tue, 09 May 2023 04:00:25 -0400 Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-158-T4XBBuLEOWqcDxRBR0goPQ-1; Tue, 09 May 2023 04:00:22 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id F21053C10696; Tue, 9 May 2023 08:00:21 +0000 (UTC) Received: from blackfin.pond.sub.org (unknown [10.39.192.121]) by smtp.corp.redhat.com (Postfix) with ESMTPS id AF71E2166B29; Tue, 9 May 2023 08:00:21 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 3842321E4AA6; Tue, 9 May 2023 10:00:11 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1683619223; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=BNCfKT61deeM62mksJwv6S1TyaJ5AQ1h8o0X7+3Q+Ig=; b=GTJQi1hkaxFwjvXcNdOJ3KanAA9n8FV71pLLOuSnwL9oDC4MqWV0QiIlQcEDiVQURADJAw oAk4bx8EQfDj627fPjWUsj2sAJ4hIP0m1liNkbsxmhxAKlXQnEbGW0XxPrfo0DA0YtKDSM 8cWiRHXwKSpf58jFL3M3Ocsca3choPs= X-MC-Unique: T4XBBuLEOWqcDxRBR0goPQ-1 From: Markus Armbruster To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, Juan Quintela Subject: [PULL 12/17] qapi: Rewrite parsing of doc comment section symbols and tags Date: Tue, 9 May 2023 10:00:06 +0200 Message-Id: <20230509080011.3231661-13-armbru@redhat.com> In-Reply-To: <20230509080011.3231661-1-armbru@redhat.com> References: <20230509080011.3231661-1-armbru@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1683619496710100001 Content-Type: text/plain; charset="utf-8" To recognize a line starting with a section symbol and or tag, we first split it at the first space, then examine the part left of the space. We can just as well examine the unsplit line, so do that. Signed-off-by: Markus Armbruster Message-Id: <20230428105429.1687850-13-armbru@redhat.com> Reviewed-by: Juan Quintela --- scripts/qapi/parser.py | 51 +++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/scripts/qapi/parser.py b/scripts/qapi/parser.py index ddc14ceaba..fc04c4573e 100644 --- a/scripts/qapi/parser.py +++ b/scripts/qapi/parser.py @@ -560,12 +560,12 @@ def end_comment(self) -> None: self._switch_section(QAPIDoc.NullSection(self._parser)) =20 @staticmethod - def _is_section_tag(name: str) -> bool: - return name in ('Returns:', 'Since:', - # those are often singular or plural - 'Note:', 'Notes:', - 'Example:', 'Examples:', - 'TODO:') + def _match_at_name_colon(string: str) -> re.Match: + return re.match(r'@([^:]*): *', string) + + @staticmethod + def _match_section_tag(string: str) -> re.Match: + return re.match(r'(Returns|Since|Notes?|Examples?|TODO): *', strin= g) =20 def _append_body_line(self, line: str) -> None: """ @@ -581,7 +581,6 @@ def _append_body_line(self, line: str) -> None: =20 Else, append the line to the current section. """ - name =3D line.split(' ', 1)[0] # FIXME not nice: things like '# @foo:' and '# @foo: ' aren't # recognized, and get silently treated as ordinary text if not self.symbol and not self.body.text and line.startswith('@'): @@ -595,12 +594,12 @@ def _append_body_line(self, line: str) -> None: self._parser, "name required after '@'") elif self.symbol: # This is a definition documentation block - if name.startswith('@') and name.endswith(':'): + if self._match_at_name_colon(line): self._append_line =3D self._append_args_line self._append_args_line(line) elif line =3D=3D 'Features:': self._append_line =3D self._append_features_line - elif self._is_section_tag(name): + elif self._match_section_tag(line): self._append_line =3D self._append_various_line self._append_various_line(line) else: @@ -621,16 +620,15 @@ def _append_args_line(self, line: str) -> None: Else, append the line to the current section. =20 """ - name =3D line.split(' ', 1)[0] - - if name.startswith('@') and name.endswith(':'): + if match :=3D self._match_at_name_colon(line): # 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. - indent =3D must_match(r'@\S*:\s*', line).end() + name =3D match.group(1) + indent =3D match.end() line =3D line[indent:] if not line: # Line was just the "@arg:" header @@ -638,8 +636,8 @@ def _append_args_line(self, line: str) -> None: indent =3D -1 else: line =3D ' ' * indent + line - self._start_args_section(name[1:-1], indent) - elif self._is_section_tag(name): + self._start_args_section(name, indent) + elif self._match_section_tag(line): self._append_line =3D self._append_various_line self._append_various_line(line) return @@ -656,16 +654,15 @@ def _append_args_line(self, line: str) -> None: self._append_freeform(line) =20 def _append_features_line(self, line: str) -> None: - name =3D line.split(' ', 1)[0] - - if name.startswith('@') and name.endswith(':'): + if match :=3D self._match_at_name_colon(line): # 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. - indent =3D must_match(r'@\S*:\s*', line).end() + name =3D match.group(1) + indent =3D match.end() line =3D line[indent:] if not line: # Line was just the "@arg:" header @@ -673,8 +670,8 @@ def _append_features_line(self, line: str) -> None: indent =3D -1 else: line =3D ' ' * indent + line - self._start_features_section(name[1:-1], indent) - elif self._is_section_tag(name): + self._start_features_section(name, indent) + elif self._match_section_tag(line): self._append_line =3D self._append_various_line self._append_various_line(line) return @@ -698,13 +695,11 @@ def _append_various_line(self, line: str) -> None: =20 Else, append the line to the current section. """ - name =3D line.split(' ', 1)[0] - - if name.startswith('@') and name.endswith(':'): + if match :=3D self._match_at_name_colon(line): raise QAPIParseError(self._parser, - "'%s' can't follow '%s' section" - % (name, self.sections[0].name)) - if self._is_section_tag(name): + "'@%s:' can't follow '%s' section" + % (match.group(1), self.sections[0].name)) + if match :=3D self._match_section_tag(line): # 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:" @@ -719,7 +714,7 @@ def _append_various_line(self, line: str) -> None: indent =3D 0 else: line =3D ' ' * indent + line - self._start_section(name[:-1], indent) + self._start_section(match.group(1), indent) =20 self._append_freeform(line) =20 --=20 2.39.2