From nobody Mon Feb 9 01:22:41 2026 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 4D1C224BC17; Mon, 24 Feb 2025 09:09:04 +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=1740388144; cv=none; b=ph785kG3PWY65bUIjDlAbYalv7QP1MlRUZt7pwGN0RwrUoQZ5mQWatduwUvATAL6ac7Xu+QxZTjC+RmAViqG6I99O5l3RJApvjAqaq5jHS/jtl7ZihDHfd6/ncnQVZ1uCp0sAjaGdQAHhhSlRO9AIR1l7GHDOAuOxf6LKCECtiI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740388144; c=relaxed/simple; bh=Y6ml/YtNkV6raER5boYfRIgmGo0cwmvZzsMQsLjY99A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pFarKa0qMePx+B2vq8P0A6hG8A6hvPFagDUkldkg5bDlvGSuPLhY1l+QLCNjj2iCbr+8vR1s49f7fENhXZQp+ZxO6ZjxYrEewxEQdNsxrntdriZSK1nU0TaZTDfbJSoykTfjQANjNagXvlU/iQpAQfp8FERHbjNkt9i6akPX6Ww= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=IRI2W4iy; 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="IRI2W4iy" Received: by smtp.kernel.org (Postfix) with ESMTPSA id AFA46C4AF0C; Mon, 24 Feb 2025 09:09:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1740388143; bh=Y6ml/YtNkV6raER5boYfRIgmGo0cwmvZzsMQsLjY99A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IRI2W4iyC77qHKENraoY4/pLd7Q9/QvbbVA4ErJmAKlMhfhIUCqqBrjsDQk0sBlNL 3lzzKVZG2gAEHieMbf7Rrn9qMypfEQJtATqb0cS1WIoWfhjWxD3QksLDiy8oHKNm2Y FLwPM6evbsR0l07retZRhVUZmYTjgA7E1XIDxvPpo2KJXhrW84oYLbpFbgMSYOgrk0 3MUqHx8FCS705oW5esuCdyDFMn1ywFx8vZrbS7wsxObIbdt7WI2B9peeFD+ErZiChG Dmp+H2C+m2DqjXFu0KCQ/2I7RB+prpmoDvjg8E7vrdCcMZK4AzrHcnGi7cp7IYKQMN Yg30Dr0uKIjGg== Received: from mchehab by mail.kernel.org with local (Exim 4.98) (envelope-from ) id 1tmUST-00000003p5z-3XLo; Mon, 24 Feb 2025 10:09:01 +0100 From: Mauro Carvalho Chehab To: Linux Doc Mailing List , Jonathan Corbet Cc: Mauro Carvalho Chehab , "Mauro Carvalho Chehab" , Kees Cook , linux-kernel@vger.kernel.org Subject: [PATCH v2 39/39] docs: sphinx: kerneldoc: Use python class if available Date: Mon, 24 Feb 2025 10:08:45 +0100 Message-ID: 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" Better integrate with the new kernel-doc tool by calling the Python classes directly if KERNELDOC=3Dscripts/kernel-doc.py. This way, warnings won't be duplicated anymore, as files will be parsed only once. Signed-off-by: Mauro Carvalho Chehab --- Documentation/sphinx/kerneldoc.py | 137 +++++++++++++++++++++++++++--- 1 file changed, 125 insertions(+), 12 deletions(-) diff --git a/Documentation/sphinx/kerneldoc.py b/Documentation/sphinx/kerne= ldoc.py index 344789ed9ea2..0758d49ee07c 100644 --- a/Documentation/sphinx/kerneldoc.py +++ b/Documentation/sphinx/kerneldoc.py @@ -41,7 +41,15 @@ import sphinx from sphinx.util.docutils import switch_source_input from sphinx.util import logging =20 +srctree =3D os.path.abspath(os.environ["srctree"]) +sys.path.insert(0, os.path.join(srctree, "scripts/lib/kdoc")) + +from kdoc_files import KernelFiles +from kdoc_output import RestFormat + __version__ =3D '1.0' +kfiles =3D None +logger =3D logging.getLogger('kerneldoc') =20 def cmd_str(cmd): """ @@ -79,14 +87,30 @@ class KernelDocDirective(Directive): 'functions': directives.unchanged, } has_content =3D False - logger =3D logging.getLogger('kerneldoc') verbose =3D 0 =20 - def run(self): + parse_args =3D {} + msg_args =3D {} + + def handle_args(self): + env =3D self.state.document.settings.env cmd =3D [env.config.kerneldoc_bin, '-rst', '-enable-lineno'] =20 filename =3D env.config.kerneldoc_srctree + '/' + self.arguments[0] + + # Arguments used by KernelFiles.parse() function + self.parse_args["file_list"] =3D [filename] + self.parse_args["export_file"] =3D [] + + # Arguments used by KernelFiles.msg() function + self.msg_args["enable_lineno"] =3D True + self.msg_args["export"] =3D False + self.msg_args["internal"] =3D False + self.msg_args["symbol"] =3D [] + self.msg_args["nosymbol"] =3D [] + self.msg_args["no_doc_sections"] =3D False + export_file_patterns =3D [] =20 verbose =3D os.environ.get("V") @@ -99,7 +123,8 @@ class KernelDocDirective(Directive): # Tell sphinx of the dependency env.note_dependency(os.path.abspath(filename)) =20 - tab_width =3D self.options.get('tab-width', self.state.document.se= ttings.tab_width) + self.tab_width =3D self.options.get('tab-width', + self.state.document.settings.tab= _width) =20 # 'function' is an alias of 'identifiers' if 'functions' in self.options: @@ -109,11 +134,15 @@ class KernelDocDirective(Directive): if 'export' in self.options: cmd +=3D ['-export'] export_file_patterns =3D str(self.options.get('export')).split= () + self.msg_args["export"] =3D True elif 'internal' in self.options: cmd +=3D ['-internal'] + self.msg_args["internal"] =3D True export_file_patterns =3D str(self.options.get('internal')).spl= it() elif 'doc' in self.options: - cmd +=3D ['-function', str(self.options.get('doc'))] + i =3D str(self.options.get('doc')) + cmd +=3D ['-function', i] + self.msg_args["symbol"].append(i) elif 'identifiers' in self.options: identifiers =3D self.options.get('identifiers').split() if identifiers: @@ -123,8 +152,10 @@ class KernelDocDirective(Directive): continue =20 cmd +=3D ['-function', i] + self.msg_args["symbol"].append(i) else: cmd +=3D ['-no-doc-sections'] + self.msg_args["no_doc_sections"] =3D True =20 if 'no-identifiers' in self.options: no_identifiers =3D self.options.get('no-identifiers').split() @@ -135,6 +166,7 @@ class KernelDocDirective(Directive): continue =20 cmd +=3D ['-nosymbol', i] + self.msg_args["nosymbol"].append(i) =20 for pattern in export_file_patterns: pattern =3D pattern.rstrip("\\").strip() @@ -144,14 +176,32 @@ class KernelDocDirective(Directive): for f in glob.glob(env.config.kerneldoc_srctree + '/' + patter= n): env.note_dependency(os.path.abspath(f)) cmd +=3D ['-export-file', f] + self.parse_args["export_file"].append(f) + + # As parse is cached, we need to pass the export_file again, + # to let the msg filter to do the right thing + + self.msg_args["export_file"] =3D self.parse_args["export_file"] + =20 cmd +=3D [filename] =20 + return cmd + + def run_cmd(self): + """ + Execute an external kernel-doc command. + """ + global logger + + env =3D self.state.document.settings.env + cmd =3D self.handle_args() + if self.verbose >=3D 1: print(cmd_str(cmd)) =20 try: - self.logger.verbose("calling kernel-doc '%s'" % (" ".join(cmd)= )) + logger.verbose("calling kernel-doc '%s'" % (" ".join(cmd))) =20 p =3D subprocess.Popen(cmd, stdout=3Dsubprocess.PIPE, stderr= =3Dsubprocess.PIPE) out, err =3D p.communicate() @@ -161,13 +211,34 @@ class KernelDocDirective(Directive): if p.returncode !=3D 0: sys.stderr.write(err) =20 - self.logger.warning("kernel-doc '%s' failed with return co= de %d" + logger.warning("kernel-doc '%s' failed with return code %d" % (" ".join(cmd), p.returncode)) return [nodes.error(None, nodes.paragraph(text =3D "kernel= -doc missing"))] elif env.config.kerneldoc_verbosity > 0: sys.stderr.write(err) =20 - lines =3D statemachine.string2lines(out, tab_width, convert_wh= itespace=3DTrue) + except Exception as e: # pylint: disable=3DW0703 + logger.warning("kernel-doc '%s' processing failed with: %s" % + (" ".join(cmd), str(e))) + return [nodes.error(None, nodes.paragraph(text =3D "kernel-doc= missing"))] + + node =3D nodes.section() + + filename =3D env.config.kerneldoc_srctree + '/' + self.arguments[0] + self.parse_msg(filename, node, out, cmd) + return node.children + + def parse_msg(self, filename, node, out, cmd): + """ + Handles a kernel-doc output for a given file + """ + + global logger + env =3D self.state.document.settings.env + + try: + lines =3D statemachine.string2lines(out, self.tab_width, + convert_whitespace=3DTrue) result =3D ViewList() =20 lineoffset =3D 0; @@ -183,20 +254,60 @@ class KernelDocDirective(Directive): result.append(line, doc + ": " + filename, lineoffset) lineoffset +=3D 1 =20 - node =3D nodes.section() self.do_parse(result, node) =20 - return node.children - except Exception as e: # pylint: disable=3DW0703 - self.logger.warning("kernel-doc '%s' processing failed with: %= s" % - (" ".join(cmd), str(e))) + logger.warning("kernel-doc '%s' processing failed with: %s" % + (cmd_str(cmd), str(e))) return [nodes.error(None, nodes.paragraph(text =3D "kernel-doc= missing"))] =20 + def run_kdoc(self, kfiles): + """ + Execute kernel-doc classes directly instead of running as a separa= te + command. + """ + + cmd =3D self.handle_args() + env =3D self.state.document.settings.env + + node =3D nodes.section() + + kfiles.parse(**self.parse_args) + filenames =3D self.parse_args["file_list"] + + for filename, out in kfiles.msg(**self.msg_args, filenames=3Dfilen= ames): + if self.verbose >=3D 1: + print(cmd_str(cmd)) + + self.parse_msg(filename, node, out, cmd) + + return node.children + + def run(self): + global kfiles + + if kfiles: + return self.run_kdoc(kfiles) + else: + return self.run_cmd() + def do_parse(self, result, node): with switch_source_input(self.state, result): self.state.nested_parse(result, 0, node, match_titles=3D1) =20 +def setup_kfiles(app): + global kfiles + + kerneldoc_bin =3D app.env.config.kerneldoc_bin + + if kerneldoc_bin and kerneldoc_bin.endswith("kernel-doc.py"): + print("Using Python kernel-doc") + out_style =3D RestFormat() + kfiles =3D KernelFiles(out_style=3Dout_style, logger=3Dlogger) + else: + print(f"Using {kerneldoc_bin}") + + def setup(app): app.add_config_value('kerneldoc_bin', None, 'env') app.add_config_value('kerneldoc_srctree', None, 'env') @@ -204,6 +315,8 @@ def setup(app): =20 app.add_directive('kernel-doc', KernelDocDirective) =20 + app.connect('builder-inited', setup_kfiles) + return dict( version =3D __version__, parallel_read_safe =3D True, --=20 2.48.1