From nobody Thu Dec 18 01:52:58 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3C1751DE88C; Mon, 10 Feb 2025 10:18:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739182705; cv=none; b=YIztloD1iAvrVfRRiMcGIbeZNXrH8WbtEXu7fL05KfIoMpLdTfqNX8IZOY7q/muK25ECUhbwjwhqXigbxRBF4si481v6S9ssKmxJg2+c4mJA5Ay37dU3WMFjaIttUuVumkN257ruAqFih5gXr0n2QVrvb8F3CCaCabwrAjZJxuw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739182705; c=relaxed/simple; bh=AgZgjsWlXG6CLe0lkuaH95ZdpSYmb1IEeyegxlm7uno=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=J2hHHPu2NZa1dEqWohchMW2m4zd3NIhUIaCaswmAThIppcNxzUf8OCw6/erCruTYU3mKIr70H6MnAV7Mqem5Yj6mZYtu5IA1D+7LeRS9rZN2NholVmwXCn+VrvDSglSoZgAaEKktlNujRysJeAV+4v8cocezzrDGCRAODBS4WoA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=PSuyVYxs; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="PSuyVYxs" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3569CC4CEFE; Mon, 10 Feb 2025 10:18:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1739182704; bh=AgZgjsWlXG6CLe0lkuaH95ZdpSYmb1IEeyegxlm7uno=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PSuyVYxsCe57ajvGphKwFMfxv95i4EQhsqHxLKP3zMy8yBLV82VsvM4yK1V4snjcx VYZuf95Ts35b5AsFHbU19H7AIw1+Iqo8SJ8fwKG5cEJWEwmXYMCFJYfuGhETlZsj4c bpdYAg8QcMGqa2UWe1LuuFZyXuc76dmxLGEV8p9VtBUdRCOC5/dPYqgdz90tVmQ3lt LSHR6tNBKvNjHfIPb5J0EPinj7/niJ2TWqGYope2yzFgufCHWUjplfzMqoYkvQhMlc PGKy+W2cPSlxgDLLrbyrR7U/ImrvF4NuK602BetNeMNgWxf4YMsBmDcZav5i7xVZ3v ut1eMrE6LZa8g== Received: from mchehab by mail.kernel.org with local (Exim 4.98) (envelope-from ) id 1thQru-00000006CjQ-1cfu; Mon, 10 Feb 2025 11:18:22 +0100 From: Mauro Carvalho Chehab To: Linux Doc Mailing List Cc: Mauro Carvalho Chehab , "Jonathan Corbet" , "Mauro Carvalho Chehab" , linux-kernel@vger.kernel.org Subject: [PATCH 20/27] docs: sphinx/kernel_abi: parse ABI files only once Date: Mon, 10 Feb 2025 11:18:09 +0100 Message-ID: <5205c53838b6ea25f4cdd4cc1e3d17c0141e75a6.1739182025.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.48.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab Content-Type: text/plain; charset="utf-8" Right now, the logic parses ABI files on 4 steps, one for each directory. While this is fine in principle, by doing that, not all symbol cross-references will be created. Change the logic to do the parsing only once in order to get a global dictionary to be used when creating ABI cross-references. Signed-off-by: Mauro Carvalho Chehab --- Documentation/admin-guide/abi-obsolete.rst | 2 +- Documentation/admin-guide/abi-removed.rst | 2 +- Documentation/admin-guide/abi-stable.rst | 2 +- Documentation/admin-guide/abi-testing.rst | 2 +- Documentation/sphinx/kernel_abi.py | 115 ++++++++++++--------- scripts/lib/abi/abi_parser.py | 22 ++-- 6 files changed, 81 insertions(+), 64 deletions(-) diff --git a/Documentation/admin-guide/abi-obsolete.rst b/Documentation/adm= in-guide/abi-obsolete.rst index 6d4d9ab7b8c3..bdef91d2cea4 100644 --- a/Documentation/admin-guide/abi-obsolete.rst +++ b/Documentation/admin-guide/abi-obsolete.rst @@ -9,4 +9,4 @@ marked to be removed at some later point in time. The description of the interface will document the reason why it is obsolete and when it can be expected to be removed. =20 -.. kernel-abi:: ABI/obsolete +.. kernel-abi:: obsolete diff --git a/Documentation/admin-guide/abi-removed.rst b/Documentation/admi= n-guide/abi-removed.rst index 9fc78af6f077..bea0608b8442 100644 --- a/Documentation/admin-guide/abi-removed.rst +++ b/Documentation/admin-guide/abi-removed.rst @@ -3,4 +3,4 @@ ABI removed symbols =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 -.. kernel-abi:: ABI/removed +.. kernel-abi:: removed diff --git a/Documentation/admin-guide/abi-stable.rst b/Documentation/admin= -guide/abi-stable.rst index c47c2a295865..33637c0d4fd5 100644 --- a/Documentation/admin-guide/abi-stable.rst +++ b/Documentation/admin-guide/abi-stable.rst @@ -12,4 +12,4 @@ for at least 2 years. Most interfaces (like syscalls) are expected to never change and always be available. =20 -.. kernel-abi:: ABI/stable +.. kernel-abi:: stable diff --git a/Documentation/admin-guide/abi-testing.rst b/Documentation/admi= n-guide/abi-testing.rst index 40b31985e587..55054985a8ff 100644 --- a/Documentation/admin-guide/abi-testing.rst +++ b/Documentation/admin-guide/abi-testing.rst @@ -18,4 +18,4 @@ Programs that use these interfaces are strongly encourage= d to add their name to the description of these interfaces, so that the kernel developers can easily notify them if any changes occur. =20 -.. kernel-abi:: ABI/testing +.. kernel-abi:: testing diff --git a/Documentation/sphinx/kernel_abi.py b/Documentation/sphinx/kern= el_abi.py index 0a4057183208..964f586de171 100644 --- a/Documentation/sphinx/kernel_abi.py +++ b/Documentation/sphinx/kernel_abi.py @@ -49,6 +49,13 @@ from abi_parser import AbiParser =20 __version__ =3D "1.0" =20 +logger =3D logging.getLogger('kernel_abi') +path =3D os.path.join(srctree, "Documentation/ABI") + +# Parse ABI symbols only once +kernel_abi =3D AbiParser(path, logger=3Dlogger) +kernel_abi.parse_abi() +kernel_abi.check_issues() =20 def setup(app): =20 @@ -64,14 +71,15 @@ class KernelCmd(Directive): u"""KernelABI (``kernel-abi``) directive""" =20 required_arguments =3D 1 - optional_arguments =3D 2 + optional_arguments =3D 3 has_content =3D False final_argument_whitespace =3D True - logger =3D logging.getLogger('kernel_abi') parser =3D None =20 option_spec =3D { "debug": directives.flag, + "no-symbols": directives.flag, + "no-files": directives.flag, } =20 def run(self): @@ -79,62 +87,67 @@ class KernelCmd(Directive): if not doc.settings.file_insertion_enabled: raise self.warning("docutils: file insertion disabled") =20 - path =3D os.path.join(srctree, "Documentation", self.arguments[0]) - self.parser =3D AbiParser(path, logger=3Dself.logger) - self.parser.parse_abi() - self.parser.check_issues() - - node =3D self.nested_parse(None, self.arguments[0]) - return node - - def nested_parse(self, data, fname): env =3D self.state.document.settings.env content =3D ViewList() node =3D nodes.section() =20 - if data is not None: - # Handles the .rst file - for line in data.split("\n"): - content.append(line, fname, 0) + abi_type =3D self.arguments[0] =20 - self.do_parse(content, node) + if "no-symbols" in self.options: + show_symbols =3D False + else: + show_symbols =3D True =20 + if "no-files" in self.options: + show_file =3D False + else: + show_file =3D True + + tab_width =3D self.options.get('tab-width', + self.state.document.settings.tab_widt= h) + + old_f =3D None + n =3D 0 + n_sym =3D 0 + for msg, f, ln in kernel_abi.doc(show_file=3Dshow_file, + show_symbols=3Dshow_symbols, + filter_path=3Dabi_type): + n_sym +=3D 1 + msg_list =3D statemachine.string2lines(msg, tab_width, + convert_whitespace=3DTrue) + if "debug" in self.options: + lines =3D [ + "", "", ".. code-block:: rst", + " :linenos:", "" + ] + for m in msg_list: + lines.append(" " + m) + else: + lines =3D msg_list + + for line in lines: + # sphinx counts lines from 0 + content.append(line, f, ln - 1) + n +=3D 1 + + if f !=3D old_f: + # Add the file to Sphinx build dependencies + env.note_dependency(os.path.abspath(f)) + + old_f =3D f + + # Sphinx doesn't like to parse big messages. So, let's + # add content symbol by symbol + if content: + self.do_parse(content, node) + content =3D ViewList() + + if show_symbols and not show_file: + logger.verbose("%s ABI: %i symbols (%i ReST lines)" % (abi_typ= e, n_sym, n)) + elif not show_symbols and show_file: + logger.verbose("%s ABI: %i files (%i ReST lines)" % (abi_type,= n_sym, n)) else: - # Handles the ABI parser content, symbol by symbol - - old_f =3D fname - n =3D 0 - for msg, f, ln in self.parser.doc(): - msg_list =3D statemachine.string2lines(msg, tab_width, - convert_whitespace=3D= True) - if "debug" in self.options: - lines =3D [ - "", "", ".. code-block:: rst", - " :linenos:", "" - ] - for m in msg_list: - lines.append(" " + m) - else: - lines =3D msg_list - - for line in lines: - # sphinx counts lines from 0 - content.append(line, f, ln - 1) - n +=3D 1 - - if f !=3D old_f: - # Add the file to Sphinx build dependencies - env.note_dependency(os.path.abspath(f)) - - old_f =3D f - - # Sphinx doesn't like to parse big messages. So, let's - # add content symbol by symbol - if content: - self.do_parse(content, node) - content =3D ViewList() - - self.logger.info("%s: parsed %i lines" % (fname, n)) + logger.verbose("%s ABI: %i data (%i ReST lines)" % (abi_type, = n_sym, n)) =20 return node.children =20 diff --git a/scripts/lib/abi/abi_parser.py b/scripts/lib/abi/abi_parser.py index 6fac461d794c..87d1b9e14bb3 100644 --- a/scripts/lib/abi/abi_parser.py +++ b/scripts/lib/abi/abi_parser.py @@ -266,12 +266,20 @@ class AbiParser: def parse_readme(self, nametag, fname): """Parse ABI README file""" =20 + nametag["what"] =3D ["ABI file contents"] + nametag["path"] =3D "README" with open(fname, "r", encoding=3D"utf8", errors=3D"backslashreplac= e") as fp: - nametag["description"] =3D "```\n" for line in fp: - nametag["description"] +=3D " " + line + match =3D self.re_tag.match(line) + if match: + new =3D match.group(1).lower() =20 - nametag["description"] +=3D "```\n" + match =3D self.re_valid.search(new) + if match: + nametag["description"] +=3D "\n:" + line + continue + + nametag["description"] +=3D line =20 def parse_file(self, fname, path, basename): """Parse a single file""" @@ -459,12 +467,8 @@ class AbiParser: continue =20 if filter_path: - if filter_path =3D=3D "README": - if not names[0].endswith("README"): - continue - else: - if v.get("path") !=3D filter_path: - continue + if v.get("path") !=3D filter_path: + continue =20 msg =3D "" =20 --=20 2.48.1