From nobody Mon Apr 6 18:53:46 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 C599E39FCDE; Wed, 18 Mar 2026 09:11:20 +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=1773825080; cv=none; b=WLByfIHQlyHLwwuAF1vYKCLQBvcwJwIRcqAkvBr5wM7TVnDvweH0vkA96bGo/6+iE9YTgfYtZU8xH7TWk/aYhh4xRaj/wvE8wZ1VgdYN1GCckdWNLL02YDHDNtRAMbFrJxyIJgTCiTkiJAIVOy1kTlCdCv9Fc1ru8h1getKSIbk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773825080; c=relaxed/simple; bh=m5R1AXbCcILaBo3xNerP4PoMfOyK0t6s1ZbCKToPNNs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=DVHtQlcIBnxlIGUbPd/i0U6LXOwhxsmLW7gQY8yHVDEeUNC+z9wzSgMnrjRCoZWufk/6mjLJPUBgsCb+3fE53k2lxAfa7Hcq/G7mF7p6q3mNGrs+AxVqaDS8g4+NMrg9kwqADPDweqwwHyTXsyXymxeZOPVSmowTJWwpmsybC9g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=UbtVRubQ; 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="UbtVRubQ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5C676C19421; Wed, 18 Mar 2026 09:11:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773825080; bh=m5R1AXbCcILaBo3xNerP4PoMfOyK0t6s1ZbCKToPNNs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UbtVRubQf8NEHQ9TwuK+JDLk+vr9iz3ePZxQ7AVpPL9G1THNE8XeqSStV/rzXj9P7 oQ38QZOa8M92hCl8k3AWy4FrQq85J9GaGu/SG0gyICokzxqsYKMwcXRXlGNxO2dZqf uGN60FovXFUPrNOPxeFI2nf1IdBc4UhGknS05PDYxBfT+vOKFQTjHt8UAOVfTxtBYU PB+sLkm5Y87lFFYxL3nJRPcZ5sHQdp/qVIF8YMiFKqVe4mfU9XbWtIG1sUNLDwGk0L IREVame0g8jJev1+ERok9NZgnvPetl2jUIebHvpkZ41tG2GOCvjd+CrRuNpe5mzt26 aTAOLSQd/2Yxg== Received: from mchehab by mail.kernel.org with local (Exim 4.99.1) (envelope-from ) id 1w2mvu-00000002fpJ-1yD9; Wed, 18 Mar 2026 10:11:18 +0100 From: Mauro Carvalho Chehab To: Jonathan Corbet , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , linux-kernel@vger.kernel.org, Mauro Carvalho Chehab Subject: [PATCH 01/14] unittests: test_tokenizer: better handle mismatch error Date: Wed, 18 Mar 2026 10:11:01 +0100 Message-ID: <6e19578bc1ffa96e536dc31997ff658017f60173.1773823995.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.53.0 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-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab The current logic is too sensitive to how c_lex name is placed. Also, it doesn't really check the log. Change it to check if the expected message will be reported after a call to C tokenizer with an invalid source. Signed-off-by: Mauro Carvalho Chehab --- tools/unittests/test_tokenizer.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/tools/unittests/test_tokenizer.py b/tools/unittests/test_token= izer.py index 5634b4a7283e..d1f3c565b9cf 100755 --- a/tools/unittests/test_tokenizer.py +++ b/tools/unittests/test_tokenizer.py @@ -46,10 +46,17 @@ def make_tokenizer_test(name, data): # # Check if logger is working # - if "log_level" in data: - with self.assertLogs('kdoc.c_lex', level=3D'ERROR') as cm: + if "log_msg" in data: + with self.assertLogs() as cm: tokenizer =3D CTokenizer(data["source"]) =20 + msg_found =3D False + for result in cm.output: + if data["log_msg"] in result: + msg_found =3D True + + self.assertTrue(msg_found, f"Missing log {data['log_msg']}= ") + return =20 # @@ -124,7 +131,7 @@ TESTS_TOKENIZER =3D { =20 "mismatch_error": { "source": "int a$ =3D 5;", # $ is illegal - "log_level": "ERROR", + "log_msg": "Unexpected token", }, } =20 --=20 2.53.0 From nobody Mon Apr 6 18:53:46 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 C83353A0E97; Wed, 18 Mar 2026 09:11:20 +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=1773825080; cv=none; b=CLI6qUD7GXrkeQHcO6k2kajEphoEhRH03Wgu04RFlxUZIVQzQzQvqMmO9Gi3Reh4zc4EFiHL3rwCL8lpldZc/nNsMXYwmnEdRc1uNT30+7dDo1rB6ADuHOqMAQLUarLrAZL4OmWTy5mKcWCKOXLxIsVQnBUicGodbsthapRar+4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773825080; c=relaxed/simple; bh=AAPYRL9TsMZyc+GIhj1XbUNzHeUMbGSOeGZaFrRqYP0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=YcglbWadyhEnlrLDpt6ZM85k06kky6Uy6t0Sbu/nfVS3JuTcDlwV6dVMYANFAqSd+/2RT0RU+8gbwwWBURYBE7K52QeoM3TXnVDT2eTcLpdfE8+0AyS/k/Oc71HE+KHScBlg+uIQ9koL9Il2STapZHAFVWGoTCahcE29+3i0A0U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=HL2UW/VL; 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="HL2UW/VL" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 60FE5C2BC9E; Wed, 18 Mar 2026 09:11:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773825080; bh=AAPYRL9TsMZyc+GIhj1XbUNzHeUMbGSOeGZaFrRqYP0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HL2UW/VLyWqk+knswcCgB2EgmCsl8ohPLqkxv08I+DVuNW8WoyMqAK/ubknH2fjXU qpnWmM/xXkZoWk19XTLPbTlUD2QZ54Q4F4rv0H9hCSiYVMXr6R4oZyt/hAm1aJeFd+ atOv00AonrmFLSgGzZQA15pb53wr7e81bJeHOR9KLRwDdB+q7qUe75kSfGQRQ0jsp5 HWi/AIPBhw9C+s1Zg7y9f1h++fuYuV4xlghIXosIHEj0Ntpm2D8FURloial8nLBnPk 3E4L3Ht2z8M9t3dJpQAw+yjiAempVytRiuxoOF1hReeHBeBZnIP8JRlXpgMZFylEel bIdCLJzhSfueQ== Received: from mchehab by mail.kernel.org with local (Exim 4.99.1) (envelope-from ) id 1w2mvu-00000002fpN-258r; Wed, 18 Mar 2026 10:11:18 +0100 From: Mauro Carvalho Chehab To: Jonathan Corbet , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , linux-kernel@vger.kernel.org, Aleksandr Loktionov , Mauro Carvalho Chehab , Randy Dunlap Subject: [PATCH 02/14] docs: kdoc_re: better represent long regular expressions Date: Wed, 18 Mar 2026 10:11:02 +0100 Message-ID: <60c264a9d277fed655b1a62df2195562c8596090.1773823995.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.53.0 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-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab The Sphinx output from autodoc doesn't automatically break long lines, except on spaces. Change KernRe __repr__() to break the pattern on multiple strings, each one with a maximum limit of 60 characters. With that, documentation output for KernRe should now be displayable, even on long strings. Signed-off-by: Mauro Carvalho Chehab --- tools/lib/python/kdoc/kdoc_re.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tools/lib/python/kdoc/kdoc_re.py b/tools/lib/python/kdoc/kdoc_= re.py index 6f3ae28859ea..28292efe25a2 100644 --- a/tools/lib/python/kdoc/kdoc_re.py +++ b/tools/lib/python/kdoc/kdoc_re.py @@ -70,10 +70,15 @@ class KernRe: =20 flags_name =3D " | ".join(flags) =20 + max_len =3D 60 + pattern =3D "" + for pos in range(0, len(self.regex.pattern), max_len): + pattern +=3D '"' + self.regex.pattern[pos:max_len + pos] + '" ' + if flags_name: - return f'KernRe("{self.regex.pattern}", {flags_name})' + return f'KernRe({pattern}, {flags_name})' else: - return f'KernRe("{self.regex.pattern}")' + return f'KernRe({pattern})' =20 def __add__(self, other): """ --=20 2.53.0 From nobody Mon Apr 6 18:53:46 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 0FF7E3A168C; Wed, 18 Mar 2026 09:11:21 +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=1773825081; cv=none; b=GT2/QbNL2d5eZvV45y8XErEBf4L9rbuJJyfNHB7vRN1uWFKB0yslk560eFKdE2Acfur4CVZfh99bbVo2OepnB6bHldt+SJp60A4Q/HmUnWe4RBrzoPXNvGWB6liQ3PVWcfHqvQ2NEgvJsdR5uk/btDMdji5aGoaGh7W8rjRxDbs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773825081; c=relaxed/simple; bh=f8IphVqFpVsPRkjyIYB/O/ozmgBwHmrUjC3r24G1VaE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=HIdQqYFZCU2GO6cAjE+6bhziQcrbtYm2+OB/5K1NQ0/M5Z9md3syk6vDJm957pTmM1rZ+CA8D10SL4XnorYeYp4HfssII8alZGLacZFXS6KqKCtltepl13vcDJVruxTMMaZDakGAkG8QigyYHl9VTTpGiNhlcL/0ljr7laRsvjs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=eZCzcgH5; 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="eZCzcgH5" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 680C1C2BCB3; Wed, 18 Mar 2026 09:11:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773825080; bh=f8IphVqFpVsPRkjyIYB/O/ozmgBwHmrUjC3r24G1VaE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eZCzcgH5VQVI7R/u0gnFuzFDIYCgG9BFjjdswx9VusjUhVEo7i1ilS6+o7qEidOxc 73t7qIhM8liCFk+sJZ/5ARSleAd59uGmbBarZgVwRSHqf/tbRBD/jYcn8nF1cWSywF D0WIU2RyWka/PTjhMrdBuJvZnOnzciHyiG0b6w6GhF2kdzVfVM9OOTDlXp7Y8i62iz vQbbqSMocfTgYbHFNruWEiq3Xd1ZaRimVsEJnJWTOtSc8yYvV8NfgcasIarZxcEZC7 IqW+adbJZb6Jxjf89BAabzI5CMT2MYvyaCv+Btr4o0pfjMoEuxAtj6+s9hga+5XGuY hKWIKe5SgQhCg== Received: from mchehab by mail.kernel.org with local (Exim 4.99.1) (envelope-from ) id 1w2mvu-00000002fpR-2BzO; Wed, 18 Mar 2026 10:11:18 +0100 From: Mauro Carvalho Chehab To: Jonathan Corbet , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , linux-kernel@vger.kernel.org, Mauro Carvalho Chehab , Shuah Khan Subject: [PATCH 03/14] docs: kdoc: add c_lex to generated documentation Date: Wed, 18 Mar 2026 10:11:03 +0100 Message-ID: <799178cf30dd4022fdb1d029ba998a458e037b52.1773823995.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.53.0 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-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab Do some fixes at groups() description for it to be parsed by Sphinx and add it to the documentation. Signed-off-by: Mauro Carvalho Chehab --- Documentation/tools/kdoc_ancillary.rst | 9 +++++++++ tools/lib/python/kdoc/c_lex.py | 9 +++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Documentation/tools/kdoc_ancillary.rst b/Documentation/tools/k= doc_ancillary.rst index 3950d0a3f104..85f3806a431a 100644 --- a/Documentation/tools/kdoc_ancillary.rst +++ b/Documentation/tools/kdoc_ancillary.rst @@ -21,6 +21,15 @@ Regular expression class handler :undoc-members: =20 =20 +C tokenizer +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +.. automodule:: lib.python.kdoc.c_lex + :members: + :show-inheritance: + :undoc-members: + + Chinese, Japanese and Korean variable fonts handler =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D =20 diff --git a/tools/lib/python/kdoc/c_lex.py b/tools/lib/python/kdoc/c_lex.py index b6d58bd470a9..e01b154f458e 100644 --- a/tools/lib/python/kdoc/c_lex.py +++ b/tools/lib/python/kdoc/c_lex.py @@ -336,13 +336,14 @@ class CTokenArgs: self.sub_tokeninzer =3D CTokenizer(sub_str) =20 def groups(self, new_tokenizer): - """ + r""" Create replacement arguments for backrefs like: =20 - ``\0``, ``\1``, ``\2``, ...``\n`` + ``\0``, ``\1``, ``\2``, ... ``\{number}`` =20 - It also accepts a ``+`` character to the highest backref. When use= d, - it means in practice to ignore delimins after it, being greedy. + It also accepts a ``+`` character to the highest backref, like + ``\4+``. When used, the backref will be greedy, picking all other + arguments afterwards. =20 The logic is smart enough to only go up to the maximum required argument, even if there are more. --=20 2.53.0 From nobody Mon Apr 6 18:53:46 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 1C84F3A5E99; Wed, 18 Mar 2026 09:11:21 +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=1773825081; cv=none; b=rRjNjqsmv9l95auVkj15HEEv68wCQi5CfGdPvYu+hVDKTAeyT82TQlzrqT/HkajrPt78hrjpBXlVKxT0CSYnMPXYc81aCVgd5hU9lr/svU0Bu6Y7hDtnLJrvdehdlH0l4mUwgB4yGZJ6891fQQJiytXywa73JwIpWUoQ5WDDjBo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773825081; c=relaxed/simple; bh=BLxIAC+0ecDESspKr2mOmfyOm7KPoCXOrsFtpwI+cOw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=NPl4ehV+IHnILCTkeWRLDDXuNWqPYy7lM4O9miTTKuU22EN5YfZcN61UIk5ezJyNjMSAj4kuK6AwYc3AQKlW04m/6yD3DfMRfPXdc6q5f/dZP/Rvt88Xphp4A03YR2eo+ngxg60GCObbrWPbn3fwBRwPPnrSyKJLb2CY/bDn088= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=QeOX7hT8; 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="QeOX7hT8" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6A41DC2BCB2; Wed, 18 Mar 2026 09:11:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773825080; bh=BLxIAC+0ecDESspKr2mOmfyOm7KPoCXOrsFtpwI+cOw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QeOX7hT8BfEHwFwAO+XNFVsZIGt+g0XWKMVx86dJQOQhIGGF3YRGOwL2rJ0Rn5xO2 p5JKfQlS2cPJWWxq6+rmkxLVrM52F4aRhEQX3zAAIT+yYoCYU1OHFLXqdZF5X3oSJp +SahHaeCo4IJ63VqJlm/2bG7HGEc1JgtAgYXJsFcPzS4ba7iGDxCGNF2bRKb8WdJRn L7Mc1y9EdqoLtBPkkGciB5J8nlEXpaHMVcZD/6MKLz9CTK/jA5enJpgUbqBub0WqXe jJJfSuspFmScwk1qGaUqPb50jDnYNSSIoQxSqCgT7ySc3TI5e3NOrMENIGoSTkhKzU fmh59tF7lYFhw== Received: from mchehab by mail.kernel.org with local (Exim 4.99.1) (envelope-from ) id 1w2mvu-00000002fpW-2JDS; Wed, 18 Mar 2026 10:11:18 +0100 From: Mauro Carvalho Chehab To: Jonathan Corbet , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , linux-kernel@vger.kernel.org, Mauro Carvalho Chehab , Randy Dunlap Subject: [PATCH 04/14] docs: kdoc_files: use a class to group config parameters Date: Wed, 18 Mar 2026 10:11:04 +0100 Message-ID: X-Mailer: git-send-email 2.53.0 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-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab Instead of abusing argparse.Namespace, define a class to store configuration parameters and logger. Signed-off-by: Mauro Carvalho Chehab --- tools/lib/python/kdoc/kdoc_files.py | 45 ++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/tools/lib/python/kdoc/kdoc_files.py b/tools/lib/python/kdoc/kd= oc_files.py index 8c2059623949..1c5cb9e5f0e8 100644 --- a/tools/lib/python/kdoc/kdoc_files.py +++ b/tools/lib/python/kdoc/kdoc_files.py @@ -9,7 +9,6 @@ Classes for navigating through the files that kernel-doc ne= eds to handle to generate documentation. """ =20 -import argparse import logging import os import re @@ -87,6 +86,28 @@ class GlobSourceFiles: file_not_found_cb(fname) =20 =20 +class KdocConfig(): + """ + Stores all configuration attributes that kdoc_parser and kdoc_output + needs. + """ + def __init__(self, verbose=3DFalse, werror=3DFalse, wreturn=3DFalse, + wshort_desc=3DFalse, wcontents_before_sections=3DFalse, + logger=3DNone): + + self.verbose =3D verbose + self.werror =3D werror + self.wreturn =3D wreturn + self.wshort_desc =3D wshort_desc + self.wcontents_before_sections =3D wcontents_before_sections + + if logger: + self.log =3D logger + else: + self.log =3D logging.getLogger(__file__) + + self.warning =3D self.log.warning + class KernelFiles(): """ Parse kernel-doc tags on multiple kernel source files. @@ -224,29 +245,25 @@ class KernelFiles(): if kdoc_werror: werror =3D kdoc_werror =20 + if not logger: + logger =3D logging.getLogger("kernel-doc") + else: + logger =3D logger + # Some variables are global to the parser logic as a whole as they= are # used to send control configuration to KernelDoc class. As such, # those variables are read-only inside the KernelDoc. - self.config =3D argparse.Namespace + self.config =3D KdocConfig(verbose, werror, wreturn, wshort_desc, + wcontents_before_sections, logger) =20 - self.config.verbose =3D verbose - self.config.werror =3D werror - self.config.wreturn =3D wreturn - self.config.wshort_desc =3D wshort_desc - self.config.wcontents_before_sections =3D wcontents_before_sections + # Override log warning, as we want to count errors + self.config.warning =3D self.warning =20 if xforms: self.xforms =3D xforms else: self.xforms =3D CTransforms() =20 - if not logger: - self.config.log =3D logging.getLogger("kernel-doc") - else: - self.config.log =3D logger - - self.config.warning =3D self.warning - self.config.src_tree =3D os.environ.get("SRCTREE", None) =20 # Initialize variables that are internal to KernelFiles --=20 2.53.0 From nobody Mon Apr 6 18:53:46 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 1C0C73A5E89; Wed, 18 Mar 2026 09:11:21 +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=1773825081; cv=none; b=RLPeB861EtlmyD0DkqyrOz0vkXu+h8gIfiZxo67Rbl5KjTVxcAWXFwcFhMfSfKsehvbET/V4OdAhAcyLDxAONe/HIFXYFVzjidQTlvdVmyx+pmy7y6x/kXTNmm5FWQZVjXyM4rTkraQ/Zacz0HM0HxFZoNFuM+yzDhyVrMFvhr8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773825081; c=relaxed/simple; bh=dOysoiiVSubxrcejiWzvM4dwgqXYUK8uzfq5tdoOHI4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=U/ip3k/ttzb6LKFPpPMbWp+8+q6Pqfos7YnB6bqj3prTMX7Coafa4FsKUvf1zPn9A5g7PZWzFUY94mL+xZuA+h3gpYx0LwmrEOyRaTq18+xrnSRmV9v20aNe9xKrq2Zz/0dvzLzQ5fJDG39LZR1qoVHH5KmAynPNUnvnQUjldwA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=nbz+tnB7; 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="nbz+tnB7" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6CA72C2BCB5; Wed, 18 Mar 2026 09:11:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773825080; bh=dOysoiiVSubxrcejiWzvM4dwgqXYUK8uzfq5tdoOHI4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nbz+tnB7kpzO6Go7QVUEXdVNoHBrdyN1ZkAtfOIWrjrcaFPlSM21KY2wzLjy1o/j5 yBLOy+qvVBnJbFmIH6zVi5hjzh78y3mw8rwcGAqBHLBM7wmc33E3togGBgM4ygduUF Qs+W0B0127N8xT108vCcKJq8iyhIk8DW+79XVYZoE5CqfZzOFkrfrnYr+eJ7uyVAWF 0JJu3cOtX5ZTRQySUp1KrVAh2IhABJMp0LVM5iLADDelrjsOOWapBqrVd9B35Q9xLB CFHoxS+LKmRxy5c10haPe9551cQPFGGrufxSFYbt+ygDAJ9DZdLc0GM83yqnM2WODL ehfOyc7JdEXzQ== Received: from mchehab by mail.kernel.org with local (Exim 4.99.1) (envelope-from ) id 1w2mvu-00000002fpa-2QJx; Wed, 18 Mar 2026 10:11:18 +0100 From: Mauro Carvalho Chehab To: Jonathan Corbet , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , linux-kernel@vger.kernel.org, Mauro Carvalho Chehab , Randy Dunlap Subject: [PATCH 05/14] docs: kdoc_files: move output symbols logic to kdoc_output Date: Wed, 18 Mar 2026 10:11:05 +0100 Message-ID: <4ebc26e37a0b544c50d50b8077760f147fa6a535.1773823995.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.53.0 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-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab When writing unittests for kdoc_output, it became clear that the logic with handles a series of KdocItem symbols from a single file belons to kdoc_output, and not to kdoc_files. Move the code to it. While here, also ensure that self.config will be placed together with set.out_style. Signed-off-by: Mauro Carvalho Chehab --- tools/lib/python/kdoc/kdoc_files.py | 18 ++---------------- tools/lib/python/kdoc/kdoc_output.py | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/tools/lib/python/kdoc/kdoc_files.py b/tools/lib/python/kdoc/kd= oc_files.py index 1c5cb9e5f0e8..58f4ee08e226 100644 --- a/tools/lib/python/kdoc/kdoc_files.py +++ b/tools/lib/python/kdoc/kdoc_files.py @@ -269,6 +269,7 @@ class KernelFiles(): # Initialize variables that are internal to KernelFiles =20 self.out_style =3D out_style + self.out_style.set_config(self.config) =20 self.errors =3D 0 self.results =3D {} @@ -311,8 +312,6 @@ class KernelFiles(): returning kernel-doc markups on each interaction. """ =20 - self.out_style.set_config(self.config) - if not filenames: filenames =3D sorted(self.results.keys()) =20 @@ -336,25 +335,12 @@ class KernelFiles(): function_table, enable_lineno, no_doc_sections) =20 - msg =3D "" if fname not in self.results: self.config.log.warning("No kernel-doc for file %s", fname) continue =20 symbols =3D self.results[fname] - self.out_style.set_symbols(symbols) - - for arg in symbols: - m =3D self.out_msg(fname, arg.name, arg) - - if m is None: - ln =3D arg.get("ln", 0) - dtype =3D arg.get('type', "") - - self.config.log.warning("%s:%d Can't handle %s", - fname, ln, dtype) - else: - msg +=3D m =20 + msg =3D self.out_style.output_symbols(fname, symbols) if msg: yield fname, msg diff --git a/tools/lib/python/kdoc/kdoc_output.py b/tools/lib/python/kdoc/k= doc_output.py index 08539dd92cbb..73d71cbeabb5 100644 --- a/tools/lib/python/kdoc/kdoc_output.py +++ b/tools/lib/python/kdoc/kdoc_output.py @@ -222,6 +222,27 @@ class OutputFormat: =20 return None =20 + def output_symbols(self, fname, symbols): + """ + Handles a set of KdocItem symbols. + """ + self.set_symbols(symbols) + + msg =3D "" + for arg in symbols: + m =3D self.msg(fname, arg.name, arg) + + if m is None: + ln =3D arg.get("ln", 0) + dtype =3D arg.get('type', "") + + self.config.log.warning("%s:%d Can't handle %s", + fname, ln, dtype) + else: + msg +=3D m + + return msg + # Virtual methods to be overridden by inherited classes # At the base class, those do nothing. def set_symbols(self, symbols): --=20 2.53.0 From nobody Mon Apr 6 18:53:46 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 C5D0D3A0B31; Wed, 18 Mar 2026 09:11:20 +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=1773825080; cv=none; b=rk5TNm7ol9ZctVihre1ctYkSK4t8kOsbDEfkvFxnUQR+9Sim/hbw+9dg3XB8j6c72ngSfdnH0ppEves/f9WVxGBa12WxdICMyowr4IoQzc/3Dhij270WSpZqm2AJcFBI4CV8Iwb/GSRZvRj7xk6spuMhlSN7n+5YO+gs/FoXHbw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773825080; c=relaxed/simple; bh=XRb9wdHvGdnLc5i1pCfLDXwMgE/fB9jkCFBFCvRmepQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=gmhC330P0vHCjXsKLRxI3ocCxAaep9EIgcOXses+9Xy15rOmP1WKPJQQtclKhKrskhwkRhbiBATqleAzJfPDAZkyJmTPHpEiMbYm+QjMQp7ydlG4h5726kIeT/5qxArL3MEuizMR7RqJJO89qZKj5N2lGM/3r/kwG74vfd1z1Ck= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=W27qKi6o; 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="W27qKi6o" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 63431C2BCAF; Wed, 18 Mar 2026 09:11:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773825080; bh=XRb9wdHvGdnLc5i1pCfLDXwMgE/fB9jkCFBFCvRmepQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=W27qKi6oYog/DKduY2jn35lbmNzVyIsQg9G+h2aEp1KRr4dEAhhrlpxM1TwZL8y/0 Jn1dW8AFsJrsg7UGhCRkmK0+DwBQAPZQMM/OmI1w3lXAkuPpCAKhGMPRQ4tbMRf5Es o9iWo3+0yOHQIfwSvUn7FVdSrOy+2geLYSA815Re/Fh0XvFPdqq2mUly5cbA1V8Xri EwLbjVaHg09e4I38AsXgwDc3qLDroZhvb2ksgOKVx7qmAPVHBNeKbzdXyLIXtnqnOZ 6vPCisvmIcwacSZkrThEZZmgThO16ZNb+U0ohg+eCMEi8KajjGso7YNc/zOWbox/X/ s3GJnc7SPZZtg== Received: from mchehab by mail.kernel.org with local (Exim 4.99.1) (envelope-from ) id 1w2mvu-00000002fpe-2XP9; Wed, 18 Mar 2026 10:11:18 +0100 From: Mauro Carvalho Chehab To: Jonathan Corbet , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , linux-kernel@vger.kernel.org, Mauro Carvalho Chehab Subject: [PATCH 06/14] docs: kdoc_item: fix initial value for parameterdesc_start_lines Date: Wed, 18 Mar 2026 10:11:06 +0100 Message-ID: <1b4ea24dd4cd82e6711e9be80168684427d74c30.1773823995.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.53.0 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-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab Ensure that parameterdesc_start_lines is a dict at init time, as this is how it will be set later on at the parser. Signed-off-by: Mauro Carvalho Chehab --- tools/lib/python/kdoc/kdoc_item.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/lib/python/kdoc/kdoc_item.py b/tools/lib/python/kdoc/kdo= c_item.py index 2b8a93f79716..c0585cdbcbd1 100644 --- a/tools/lib/python/kdoc/kdoc_item.py +++ b/tools/lib/python/kdoc/kdoc_item.py @@ -22,7 +22,7 @@ class KdocItem: self.sections =3D {} self.sections_start_lines =3D {} self.parameterlist =3D [] - self.parameterdesc_start_lines =3D [] + self.parameterdesc_start_lines =3D {} self.parameterdescs =3D {} self.parametertypes =3D {} # --=20 2.53.0 From nobody Mon Apr 6 18:53:46 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 C2E7D39F169; Wed, 18 Mar 2026 09:11:20 +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=1773825080; cv=none; b=oRGDPkaut8b2yJCOUnjWjj6OUGcJ6JmI22n7f0ObqdiXq1zQeWBrNhXuQ+VAaur5+cH4myyxePBA3ZjEO5wuQUFgegAZ35rJDwFJ6VKoXvClo8wst9+vd2BAxL1Fo28uMZzIv4mj3+inFVY9uhJdGzLxV4OtvsyBnHnYfeEcSCw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773825080; c=relaxed/simple; bh=nBQ14W9/TnksHUfJjA8FVeDj3iQtD4VD4UidbU9q+Pw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=DXozSXvBwmOAd83anAcJzATBO4dXMceSoPkEfOJddvJESAkO6Wv1nDnEFXIjAOY/3y5lPrVFmfO8G65p5s1//1ouh9OuuAHHQoxJbzmetRYZZANZwb9Xo7L35UheqfMzlQwlSTAd5YLXDE+dV01CUe7n99MLXRsrH/3qg2SKSgU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MPICeKuq; 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="MPICeKuq" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 65C35C2BC87; Wed, 18 Mar 2026 09:11:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773825080; bh=nBQ14W9/TnksHUfJjA8FVeDj3iQtD4VD4UidbU9q+Pw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MPICeKuq7ZktL64ab2ev/n6bMNvRYlt02pOtbtgYdSMtOMLD4tWMZhJZEArhNI4ID S9wrX048aUV3quXYNdMar6rXZlz0BWxVBG+cx+XgxeVYCgUc3QQQWBfSFUdVhHxSoU hCbMhPoyGKZiyZnNke3WP2tGTvynoVJJPf424Z/YCFl2mMSOJrDJ7imLUbGOxdHkt7 fZdA+aq4BK2zRuPPP5sSrUVzmS4+UkJtwORBQ8AIfHE9Omz7oLgCMIQ6ERtFIUi46d uyVc52t147YJxDVKYQNPQvfyb1AetJRLFE9P+xPDPEP5qUCkntbFxUJkb+ud0UxNeq Qm0lPb4ui2Qcw== Received: from mchehab by mail.kernel.org with local (Exim 4.99.1) (envelope-from ) id 1w2mvu-00000002fpi-2eOa; Wed, 18 Mar 2026 10:11:18 +0100 From: Mauro Carvalho Chehab To: Jonathan Corbet , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , linux-kernel@vger.kernel.org, Mauro Carvalho Chehab Subject: [PATCH 07/14] docs: kdoc_item: add support to generate a KdocItem from a dict Date: Wed, 18 Mar 2026 10:11:07 +0100 Message-ID: X-Mailer: git-send-email 2.53.0 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-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab When reading the contents on a KdocItem using YAML, the data will be imported into a dict. Add a method to create a new KdocItem from a dict to allow converting such input into a real KdocItem. While here, address an issue that, if the class is initialized with an internal parameter outside the 4 initial arguments, it would end being added inside other_stuff, which breaks initializing it from a dict. Signed-off-by: Mauro Carvalho Chehab --- tools/lib/python/kdoc/kdoc_item.py | 35 +++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/tools/lib/python/kdoc/kdoc_item.py b/tools/lib/python/kdoc/kdo= c_item.py index c0585cdbcbd1..5f41790efacb 100644 --- a/tools/lib/python/kdoc/kdoc_item.py +++ b/tools/lib/python/kdoc/kdoc_item.py @@ -25,12 +25,31 @@ class KdocItem: self.parameterdesc_start_lines =3D {} self.parameterdescs =3D {} self.parametertypes =3D {} + + self.warnings =3D [] + # # Just save everything else into our own dict so that the output # side can grab it directly as before. As we move things into more # structured data, this will, hopefully, fade away. # - self.other_stuff =3D other_stuff + known_keys =3D { + 'declaration_start_line', + 'sections', + 'sections_start_lines', + 'parameterlist', + 'parameterdesc_start_lines', + 'parameterdescs', + 'parametertypes', + 'warnings', + } + + self.other_stuff =3D {} + for k, v in other_stuff.items(): + if k in known_keys: + setattr(self, k, v) # real attribute + else: + self.other_stuff[k] =3D v =20 def get(self, key, default =3D None): """ @@ -41,6 +60,20 @@ class KdocItem: def __getitem__(self, key): return self.get(key) =20 + @classmethod + def from_dict(cls, d): + """Create a KdocItem from a plain dict.""" + + cp =3D d.copy() + name =3D cp.pop('name', None) + fname =3D cp.pop('fname', None) + type =3D cp.pop('type', None) + start_line =3D cp.pop('start_line', 1) + other_stuff =3D cp.pop('other_stuff', {}) + + # Everything that=E2=80=99s left goes straight to __init__ + return cls(name, fname, type, start_line, **cp, **other_stuff) + # # Tracking of section and parameter information. # --=20 2.53.0 From nobody Mon Apr 6 18:53:46 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 1A8523A5E84; Wed, 18 Mar 2026 09:11:21 +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=1773825081; cv=none; b=jHNfIq/JM95yuZ0B2NR6NGpd38fPbqcBB5uTlk38SO1kzR/k/SRLKDWW3WnBQ/i0ON6Ax3EYeGMR9Y+cq43B5oHqtCdouMODoyHKMlat49Rv6IKIaxmaveNPC2zaFIvTg2G7kJ2Pk6+ImhjJWQF8ImT26ee8Qsvzfa8IdPZQdc8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773825081; c=relaxed/simple; bh=Kho/SfdXlAhptQOMVPd0Peuv9YWwg6RMPsq15weyqbI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=QgJTPB1H51aQs8cXW4Oxyu6yJPgWbRfFQ/2mSLcQeuQrglZ8muEv+Slq5ehzJ5pqzpn5+1j559Ubr+2aQdYk3v7KLNoKUXtzR+Fx3EgssWkPhDKteCXl58HnYRpXsyE7Pv/KQPC8vkZ+8c0A19nBJp/u90rBmIVqIUTxwirnx8c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Qr3SdTAI; 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="Qr3SdTAI" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6F16FC2BCB4; Wed, 18 Mar 2026 09:11:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773825080; bh=Kho/SfdXlAhptQOMVPd0Peuv9YWwg6RMPsq15weyqbI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Qr3SdTAIi4qOwu+yIHvjhmw59zZSAjdewzbb0m9ZfGJ9/udz07CPtcL21Mp4o2+Qu v58U1SN21lBLaXoMbxzhbd4pyZlbULjICPXuz9Bm5rAveNFrREXN2YeD/qPbRZ8tGK 6aHFm4E/xvXPq+X/LXwaN79u+q6+GdCbkVWV/mC2Y/HZUYA2qeCyYYvnugibH9gilR Acgj+tMdZ+TnSGdQaugejfWnvh8nFblBiDfejra2EjwyjPx8jRZo6YG+CAR8dp+/HA pjXeRN/jNKPm7IOEyufCaPk9ZgMaAVby9nxbt85oqi80ExI6MXUbqKQ1DVUrglM9ON YPSiUwGnQRIXg== Received: from mchehab by mail.kernel.org with local (Exim 4.99.1) (envelope-from ) id 1w2mvu-00000002fpm-2lDF; Wed, 18 Mar 2026 10:11:18 +0100 From: Mauro Carvalho Chehab To: Jonathan Corbet , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , linux-kernel@vger.kernel.org, Aleksandr Loktionov , Mauro Carvalho Chehab , Randy Dunlap Subject: [PATCH 08/14] docs: kdoc_item: fix a typo on sections_start_lines Date: Wed, 18 Mar 2026 10:11:08 +0100 Message-ID: X-Mailer: git-send-email 2.53.0 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-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab Currently, there are 15 occurrences of section?_start_lines, with 10 using the plural way. This is an issue, as, while kdoc_output works with KdocItem, the term doesn't match its init value. The variable sections_start_lines stores multiple sections, so placing it in plural is its correct way. So, ensure that, on all parts of kdoc, this will be referred as sections_start_lines. Signed-off-by: Mauro Carvalho Chehab --- tools/lib/python/kdoc/kdoc_item.py | 2 +- tools/lib/python/kdoc/kdoc_output.py | 2 +- tools/lib/python/kdoc/kdoc_parser.py | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/lib/python/kdoc/kdoc_item.py b/tools/lib/python/kdoc/kdo= c_item.py index 5f41790efacb..fe08cac861c2 100644 --- a/tools/lib/python/kdoc/kdoc_item.py +++ b/tools/lib/python/kdoc/kdoc_item.py @@ -82,7 +82,7 @@ class KdocItem: Set sections and start lines. """ self.sections =3D sections - self.section_start_lines =3D start_lines + self.sections_start_lines =3D start_lines =20 def set_params(self, names, descs, types, starts): """ diff --git a/tools/lib/python/kdoc/kdoc_output.py b/tools/lib/python/kdoc/k= doc_output.py index 73d71cbeabb5..1b54117dbe19 100644 --- a/tools/lib/python/kdoc/kdoc_output.py +++ b/tools/lib/python/kdoc/kdoc_output.py @@ -389,7 +389,7 @@ class RestFormat(OutputFormat): else: self.data +=3D f'{self.lineprefix}**{section}**\n\n' =20 - self.print_lineno(args.section_start_lines.get(section, 0)) + self.print_lineno(args.sections_start_lines.get(section, 0)) self.output_highlight(text) self.data +=3D "\n" self.data +=3D "\n" diff --git a/tools/lib/python/kdoc/kdoc_parser.py b/tools/lib/python/kdoc/k= doc_parser.py index f6c4ee3b18c9..35658a7e72d5 100644 --- a/tools/lib/python/kdoc/kdoc_parser.py +++ b/tools/lib/python/kdoc/kdoc_parser.py @@ -140,7 +140,7 @@ class KernelEntry: self.parametertypes =3D {} self.parameterdesc_start_lines =3D {} =20 - self.section_start_lines =3D {} + self.sections_start_lines =3D {} self.sections =3D {} =20 self.anon_struct_union =3D False @@ -220,7 +220,7 @@ class KernelEntry: self.sections[name] +=3D '\n' + contents else: self.sections[name] =3D contents - self.section_start_lines[name] =3D self.new_start_line + self.sections_start_lines[name] =3D self.new_start_line self.new_start_line =3D 0 =20 # self.config.log.debug("Section: %s : %s", name, pformat(vars(self= ))) @@ -316,7 +316,7 @@ class KernelDoc: for section in ["Description", "Return"]: if section in sections and not sections[section].rstrip(): del sections[section] - item.set_sections(sections, self.entry.section_start_lines) + item.set_sections(sections, self.entry.sections_start_lines) item.set_params(self.entry.parameterlist, self.entry.parameterdesc= s, self.entry.parametertypes, self.entry.parameterdesc_start_lines) --=20 2.53.0 From nobody Mon Apr 6 18:53:46 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 15B2E3A4F4B; Wed, 18 Mar 2026 09:11:21 +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=1773825081; cv=none; b=bPqboPwdp9UQtcEdIpg7GV8NKkmbttgiy58EUImjxUgka8qEGKJ1mCS+yeF1ekDgySTcDKidtank2W2OfnuH/7sAedtbxqpYKZk04/2gp1JIZRdKX7KihBHUEAqP5IMXVFkKY1bG5VJ+CmPnARpM8lgmAaKPKBL2rXjMk0MkGeM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773825081; c=relaxed/simple; bh=+LuCPjCencCh9Cs3UwkM42H1Wvio+AUTLkCST6A38F8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=cKEc3khjBqCl6ZVhPJRdABEpsTExm2+AyqjUnHFkHduQBIATI+wd8/yKSW5MS7Ask7u88G2FfGRWmSKwpkvjJ8sJYTv+s3R9sJyt6AVpZsQVOo/JHXWYrUREAbtfrh+OQhX+wwTOVgoJcUt1Jc0kl4Z3zX/rC3/7VGTrIb5mM0I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=G5ymZDMY; 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="G5ymZDMY" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 715C0C2BCB7; Wed, 18 Mar 2026 09:11:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773825080; bh=+LuCPjCencCh9Cs3UwkM42H1Wvio+AUTLkCST6A38F8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=G5ymZDMYCAWKEom3QCcGq90Fsrf4HcMpPzz9HvFW/UKSZ6MZ7azRx9KVL+YlIMhfs jzsQr34W15Icm6P/B92rGLb9ZC5fXdDw5ijmApnUajbpD8kILKzO/kTOSye6z7GBNi vn1WNsfomSFHcc9xANox5MIcEl0BlcPxgLVCShr1yX5Zt2jND286wPDujXlJIKFFDe AfRm/VVwODns15LXUwL8zm2rsY9f32ZKMNIYRsTvNfQsAjRArxwe5rl/MyQ8nyJ2oZ H1JnLpqPAMYOO3mbUddVScgHHZL50JPxrsGQVbEbISbiUzjUecDNTDwLFB3Vw+Epk2 QSO5aFtaP+5VA== Received: from mchehab by mail.kernel.org with local (Exim 4.99.1) (envelope-from ) id 1w2mvu-00000002fpq-2sJj; Wed, 18 Mar 2026 10:11:18 +0100 From: Mauro Carvalho Chehab To: Jonathan Corbet , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , linux-kernel@vger.kernel.org, Mauro Carvalho Chehab Subject: [PATCH 09/14] docs: unittests: add a parser to test kernel-doc parser logic Date: Wed, 18 Mar 2026 10:11:09 +0100 Message-ID: <8d91bfabd69de7aa44a0f5080ccb01aa41957e6d.1773823995.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.53.0 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-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab Validating that kernel-doc is parsing data properly is tricky. Add an unittest skeleton that alllows passing a source code and check if the corresponding values of export_table and entries returned by the parser are properly filled. It works by mocking a file input with the contents of a source string, an comparing if: - exports set matches; - expected KernelItem entries match. Create a new TestSelfValidate meant to check if the logic inside KdocParser.run_test() does its job of checking for differences inside KdocItem. Signed-off-by: Mauro Carvalho Chehab --- tools/unittests/test_kdoc_parser.py | 202 ++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100755 tools/unittests/test_kdoc_parser.py diff --git a/tools/unittests/test_kdoc_parser.py b/tools/unittests/test_kdo= c_parser.py new file mode 100755 index 000000000000..26f74666a000 --- /dev/null +++ b/tools/unittests/test_kdoc_parser.py @@ -0,0 +1,202 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0 +# Copyright(c) 2026: Mauro Carvalho Chehab . +# +# pylint: disable=3DC0200,C0413,W0102,R0914 + +""" +Unit tests for kernel-doc parser. +""" + +import os +import unittest +import re +import sys + +from textwrap import dedent +from unittest.mock import patch, MagicMock, mock_open + +SRC_DIR =3D os.path.dirname(os.path.realpath(__file__)) +sys.path.insert(0, os.path.join(SRC_DIR, "../lib/python")) + +from kdoc.kdoc_parser import KernelDoc +from kdoc.kdoc_item import KdocItem +from kdoc.xforms_lists import CTransforms +from unittest_helper import run_unittest + +#: Regex to help cleaning whitespaces +RE_WHITESPC =3D re.compile(r"\s++") + +def clean_whitespc(val, relax_whitespace=3DFalse): + """ + Cleanup whitespaces to avoid false positives. + + By default, strip only bein/end whitespaces, but, when relax_whitespace + is true, also replace multiple whitespaces in the middle. + """ + + if isinstance(val, str): + val =3D val.strip() + if relax_whitespace: + val =3D RE_WHITESPC.sub("", val) + elif isinstance(val, list): + val =3D [clean_whitespc(item, relax_whitespace) for item in val] + elif isinstance(val, dict): + val =3D {k: clean_whitespc(v, relax_whitespace) for k, v in val.it= ems()} + return val + +# +# Helper class to help mocking with +# +class KdocParser(unittest.TestCase): + """ + Base class to run KernelDoc parser class + """ + + DEFAULT =3D vars(KdocItem("", "", "", 0)) + + def setUp(self): + self.maxDiff =3D None + self.config =3D MagicMock() + self.config.log =3D MagicMock() + self.config.log.debug =3D MagicMock() + self.xforms =3D CTransforms() + + + def run_test(self, source, __expected_list, exports=3D{}, fname=3D"tes= t.c", + relax_whitespace=3DFalse): + """ + Stores expected values and patch the test to use source as + a "file" input. + """ + debug_level =3D int(os.getenv("VERBOSE", "0")) + source =3D dedent(source) + + # Ensure that default values will be there + expected_list =3D [] + for e in __expected_list: + new_e =3D self.DEFAULT.copy() + new_e["fname"] =3D fname + for key, value in e.items(): + new_e[key] =3D value + + expected_list.append(new_e) + + patcher =3D patch('builtins.open', + new_callable=3Dmock_open, read_data=3Dsource) + + kernel_doc =3D KernelDoc(self.config, fname, self.xforms) + + with patcher: + export_table, entries =3D kernel_doc.parse_kdoc() + + self.assertEqual(export_table, exports) + self.assertEqual(len(entries), len(expected_list)) + + for i in range(0, len(entries)): + + entry =3D entries[i] + expected =3D expected_list[i] + self.assertNotEqual(expected, None) + self.assertNotEqual(expected, {}) + self.assertIsInstance(entry, KdocItem) + + d =3D vars(entry) + for key, value in expected.items(): + result =3D clean_whitespc(d[key], relax_whitespace) + value =3D clean_whitespc(value, relax_whitespace) + + if debug_level > 1: + sys.stderr.write(f"{key}: assert('{result}' =3D=3D= '{value}')\n") + + self.assertEqual(result, value, msg=3Df"at {key}") + + +# +# Selttest class +# +class TestSelfValidate(KdocParser): + """ + Tests to check if logic inside KdocParser.run_test() is working. + """ + + SOURCE =3D """ + /** + * function3: Exported function + * @arg1: @arg1 does nothing + * + * Does nothing + * + * return: + * always return 0. + */ + int function3(char *arg1) { return 0; }; + EXPORT_SYMBOL(function3); + """ + + EXPECTED =3D [{ + 'name': 'function3', + 'type': 'function', + 'declaration_start_line': 2, + + 'sections_start_lines': { + 'Description': 4, + 'Return': 7, + }, + 'sections': { + 'Description': 'Does nothing\n\n', + 'Return': '\nalways return 0.\n' + }, + 'other_stuff': { + 'func_macro': False, + 'functiontype': 'int', + 'purpose': 'Exported function', + 'typedef': False + }, + 'parameterdescs': {'arg1': '@arg1 does nothing\n'}, + 'parameterlist': ['arg1'], + 'parameterdesc_start_lines': {'arg1': 3}, + 'parametertypes': {'arg1': 'char *arg1'}, + }] + + EXPORTS =3D {"function3"} + + def test_parse_pass(self): + """ + Test if export_symbol is properly handled. + """ + self.run_test(self.SOURCE, self.EXPECTED, self.EXPORTS) + + @unittest.expectedFailure + def test_no_exports(self): + """ + Test if export_symbol is properly handled. + """ + self.run_test(self.SOURCE, [], {}) + + @unittest.expectedFailure + def test_with_empty_expected(self): + """ + Test if export_symbol is properly handled. + """ + self.run_test(self.SOURCE, [], self.EXPORTS) + + @unittest.expectedFailure + def test_with_unfilled_expected(self): + """ + Test if export_symbol is properly handled. + """ + self.run_test(self.SOURCE, [{}], self.EXPORTS) + + @unittest.expectedFailure + def test_with_default_expected(self): + """ + Test if export_symbol is properly handled. + """ + self.run_test(self.SOURCE, [self.DEFAULT.copy()], self.EXPORTS) + +# +# Run all tests +# +if __name__ =3D=3D "__main__": + run_unittest(__file__) --=20 2.53.0 From nobody Mon Apr 6 18:53:46 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 0568039E16C; Wed, 18 Mar 2026 09:11:21 +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=1773825081; cv=none; b=q86CLMiCZCuZPB4jNZpLM2TfhbYJHAva8P9x96vOWyQ0MReDgGIfjkSiJmVDcAQa1VjYBDToN1Bwz/6fqNKQBBS9mTKKAQsNOEdlzZWCCVEKTV5E//7WBXZavFuPL8ZRGsO96xo0x9FZjmjEL4c0mgso9QGzbDyhN/y09fB8W5A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773825081; c=relaxed/simple; bh=X1yEX8lbYO0S5xeoDrx5PLqGmHxcZe9gt4OR2H1Y1no=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=mS3L2fKNaV8oI958X6hGBXT+HIpu8Nm4UZK7kXQFF/N3VY1XwqWmRzJEgDHfQrwuh3nWh/Q17ho+yY+x2OnM+P6zAYbYTOUBz+5eV/2QRABrAkVQ+n0iAza2x7zClxfaoeSa4iKLlwdNs2zFVBhPeWBXJZApUeDoFmfoa/Je0oQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=O44EzMM3; 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="O44EzMM3" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7D38DC2BCC4; Wed, 18 Mar 2026 09:11:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773825080; bh=X1yEX8lbYO0S5xeoDrx5PLqGmHxcZe9gt4OR2H1Y1no=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=O44EzMM3fkg8xY0/+XIe0G63xhtWyglXyLSFymMQq29oF2tz5uh67C9hiheDrKn+L pJmsdCvm7VYO6SVRxH4mlJdQLGvSBK6Ot1BSLJ5phzD39LjOeBN8WBdvbIYCmFP3r1 8wiXN+lIsfxWEMPz9l/A1Nh0eif+jtQu19qbwrCFKsF7Quk8n/4rG9V306TtCs1ioh IYfVnEDhaDBkYFreIS3r5j14AVO7K5BY17LghKcCy2sNFqc54bhJPFtGwF9ITFxJpo SrRj25CEuSo8NbHNpU87tSHM/x2lYZiZUfwf9Ccdx8Z+Wc6hdUfbUntkKq7KBSzmHH /4iqJHOL7YXGw== Received: from mchehab by mail.kernel.org with local (Exim 4.99.1) (envelope-from ) id 1w2mvu-00000002fpu-2zA8; Wed, 18 Mar 2026 10:11:18 +0100 From: Mauro Carvalho Chehab To: Jonathan Corbet , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , linux-kernel@vger.kernel.org, Carvalho Chehab Subject: [PATCH 10/14] docs: add a schema to help creating unittests for kernel-doc Date: Wed, 18 Mar 2026 10:11:10 +0100 Message-ID: X-Mailer: git-send-email 2.53.0 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-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab Instead of hardcoding lots of tests inside a file, let's place them inside a yaml file. Add first a schema to handle it. Signed-off-by: Mauro Carvalho Chehab --- tools/unittests/kdoc-test-schema.yaml | 156 ++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 tools/unittests/kdoc-test-schema.yaml diff --git a/tools/unittests/kdoc-test-schema.yaml b/tools/unittests/kdoc-t= est-schema.yaml new file mode 100644 index 000000000000..cf5079711cd8 --- /dev/null +++ b/tools/unittests/kdoc-test-schema.yaml @@ -0,0 +1,156 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright(c) 2026: Mauro Carvalho Chehab . + +# KDoc Test File Schema + +# This schema contains objects and properties needed to run kernel-doc +# self-tests. + +$schema: "http://json-schema.org/draft-07/schema#" + +tests: + type: array + minItems: 1 + description: | + A list of kernel-doc tests. + + properties: + type: object + properties: + name: + type: string + description: | + Test name. Should be an unique identifier within the schema. + Don't prepend it with "test", as the dynamic test creation will + do it. + + description: + type: string + description: | + Test description + + source: + type: string + description: | + C source code that should be parsed by kernel-doc. + + fname: + type: string + description: | + The filename that contains the element. + When placing real testcases, please use here the name of + the C file (or header) from where the source code was picked. + + exports: + type: array + items: { type: string } + description: | + A list of export identifiers that are expected when parsing sour= ce. + + expected: + type: array + minItems: 1 + description: | + A list of expected values. This list consists on objects to check + both kdoc_parser and/or kdoc_output objects. + + items: + type: object + properties: + # + # kdoc_item + # + kdoc_item: + type: object + description: | + Object expected to represent the C source code after parsed + by tools/lib/python/kdoc/kdoc_parser.py KernelDoc class. + See tools/lib/python/kdoc/kdoc_item.py for its contents. + + properties: + name: + type: string + description: | + The name of the identifier (function name, struct name= , etc). + type: + type: string + description: | + Type of the object, as filled by kdoc_parser. can be: + - enum + - typedef + - union + - struct + - var + - function + declaration_start_line: + type: integer + description: | + The line number where the kernel-doc markup started. + The first line of the code is line number 1. + sections: + type: object + additionalProperties: { type: string } + description: | + Sections inside the kernel-doc markups: + - "description" + - "return" + - any other part of the markup that starts with "somet= hing:" + sections_start_lines: + type: object + additionalProperties: { type: integer } + description: | + a list of section names and the starting line of it. + parameterlist: + type: array + items: { type: string } + description: | + Ordered list of parameter names. + + parameterdesc_start_lines: + type: object + additionalProperties: { type: integer } + description: | + Mapping from parameter name to the line where its + description starts. + parameterdescs: + type: object + additionalProperties: { type: string } + description: | + Mapping from parameter name to its description. + + parametertypes: + type: object + additionalProperties: { type: string } + description: | + Mapping from parameter name to its type. + + other_stuff: + type: object + additionalProperties: {} + description: | + Extra properties that will be stored at the item. + Should match what kdoc_output expects. + + required: + - name + - type + - declaration_start_line + + rst: + type: string + description: | + The expected output for RestOutput class. + + man: + type: string + description: | + The expected output for ManOutput class. + + anyOf: + required: kdoc_item + required: source + + required: + - name + - fname + - expected --=20 2.53.0 From nobody Mon Apr 6 18:53:46 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 14C433A4F44; Wed, 18 Mar 2026 09:11:21 +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=1773825081; cv=none; b=Tdk7X6bMLOPy7ky6tAmtzWivgXg36twbHQxH9qceay5mRsoiZelzqEGejW8b71XCbU41wx5q8QPNeWRqAlZp2R1M3ZKhwEgpoTwizlffr6foIChj42N3P0vbFMrSpWVsZZQaKTg4iJIetb/zZiaXT6cFe/sWCGX9WzOLQzQKgZY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773825081; c=relaxed/simple; bh=pG4yNDPd52x57hQuewPFl0zHI66ri1EkY8+dE1xzdJQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=I8RRXz32evfEP70lFbF/eLGo1vwiIriixR4LQD6Jwti9y9eTtqqdh9tJlyCpt7Kh8ZVY0jYr4K4ZKayg9NnqvtxDMgoW9pRMWv6vP38he7kMVjN2xAnJu0ZrwYCNdG0t0C5Pb113AvPrE2NnU6+2YEDNeFj5HVHOB8/TONVHTRg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=n2Q7eAnK; 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="n2Q7eAnK" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 74EE3C2BCB6; Wed, 18 Mar 2026 09:11:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773825080; bh=pG4yNDPd52x57hQuewPFl0zHI66ri1EkY8+dE1xzdJQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=n2Q7eAnKdmMMTOr6iY9yzmXFGPml2GCXAiR8smMRGP+Pd/yGI5nTc/AXYTUmFI5lb g82toSnsaPA+QYLtckukh2bALvxg4RCYyRJ+nEvsi/kWaBVX6iIZhrfrN8NlCBuVhu RBMJbNGgPZNVh3Urj7wnSczDgUZeTWZMZdSbwQm3QGD1WBJ3/FXVOJeVWoPXjxx3ed 3oGpZ9H+5p1cQoF0d6TiVxnz1lxjsuDUfmqymg7zrbBdN7XiRvGHFSHtNYYdn6+6JX bjW/kmTP32Zy6OCtiL3cbBXMpJw2DCkv+SiJfFTHdgCYJlWthdVGEZZ2JiirnlpgUl Y+rjPEJz7M/QQ== Received: from mchehab by mail.kernel.org with local (Exim 4.99.1) (envelope-from ) id 1w2mvu-00000002fpy-37Br; Wed, 18 Mar 2026 10:11:18 +0100 From: Mauro Carvalho Chehab To: Jonathan Corbet , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , linux-kernel@vger.kernel.org, Carvalho Chehab Subject: [PATCH 11/14] docs: add a simple kdoc-test.yaml together with a validation tool Date: Wed, 18 Mar 2026 10:11:11 +0100 Message-ID: <74883976348c964f00161696d525c33ddd8c7641.1773823995.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.53.0 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-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab Create a simple kdoc-test.yaml to be used to create unit tests for kernel-doc parser and output classes. For now, all we want is a simple function mapped on a yaml test using the defined schema. To be sure that the schema is followed, add an unittest for the file, which will also validate that the schema is properly parsed. It should be noticed that the .TH definition for the man format contains a timestamp. We'll need to handle that when dealing with the actual implementation for the ManOutput class unit tests. Signed-off-by: Mauro Carvalho Chehab --- tools/unittests/kdoc-test.yaml | 154 +++++++++++++++++++++++ tools/unittests/test_kdoc_test_schema.py | 94 ++++++++++++++ 2 files changed, 248 insertions(+) create mode 100644 tools/unittests/kdoc-test.yaml create mode 100755 tools/unittests/test_kdoc_test_schema.py diff --git a/tools/unittests/kdoc-test.yaml b/tools/unittests/kdoc-test.yaml new file mode 100644 index 000000000000..b6e04f10ccdb --- /dev/null +++ b/tools/unittests/kdoc-test.yaml @@ -0,0 +1,154 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2026: Mauro Carvalho Chehab + +# Test cases for the dynamic tests. +# Useful to test if kernel-doc classes are doing what it is expected. +# + +tests: +- name: func1 + fname: mock_functions.c + description: "Simplest function test: do nothing, just rst output" + + source: | + /** + * func1 - Not exported function + * @arg1: @arg1 does nothing + * + * Does nothing + * + * return: + * always return 0. + */ + int func1(char *arg1) { return 0; }; + + + expected: + - rst: | + .. c:function:: int func1 (char *arg1) + + Not exported function + + .. container:: kernelindent + + **Parameters** + + ``char *arg1`` + **arg1** does nothing + + **Description** + + Does nothing + + **Return** + + always return 0. + + # TODO: how to handle timestamps at .TH? + man: | + .TH "func1" 9 "February 2026" "" "Kernel API Manual" + .SH NAME + func1 \- Not exported function + .SH SYNOPSIS + .B "int" func1 + .BI "(char *arg1 " ");" + .SH ARGUMENTS + .IP "arg1" 12 + \fIarg1\fP does nothing + .SH "DESCRIPTION" + Does nothing + .SH "RETURN" + always return 0. + .SH "SEE ALSO" + .PP + Kernel file \fBmock_functions.c\fR + +- name: func2 + fname: func2.c + description: Simple test with exports + + source: | + /** + * func2() - Exported function + * @arg1: @arg1 does nothing + * + * Does nothing + * + * return: + * always return 0. + */ + int func2(char *arg1) { return 0; }; + EXPORT_SYMBOL(func2); + + exports: func2 + expected: + - kdoc_item: + name: func2 + type: function + declaration_start_line: 1 + + sections: + Description: | + Does nothing + + Return: | + always return 0. + + sections_start_lines: + Description: 3 + Return: 6 + + parameterdescs: + arg1: | + @arg1 does nothing + parameterlist: + - arg1 + parameterdesc_start_lines: + arg1: 2 + parametertypes: + arg1: char *arg1 + + other_stuff: + func_macro: false + functiontype: int + purpose: "Exported function" + typedef: false + + rst: | + .. c:function:: int func2 (char *arg1) + + Exported function + + .. container:: kernelindent + + **Parameters** + + ``char *arg1`` + **arg1** does nothing + + **Description** + + Does nothing + + **Return** + + always return 0. + + # TODO: how to handle timestamps at .TH? + man: | + .TH "func2" 9 "February 2026" "" "Kernel API Manual" + .SH NAME + func2 \- Exported function + .SH SYNOPSIS + .B "int" func2 + .BI "(char *arg1 " ");" + .SH ARGUMENTS + .IP "arg1" 12 + \fIarg1\fP does nothing + .SH "DESCRIPTION" + Does nothing + .SH "RETURN" + always return 0. + .SH "SEE ALSO" + .PP + Kernel file \fBfunc2.c\fR diff --git a/tools/unittests/test_kdoc_test_schema.py b/tools/unittests/tes= t_kdoc_test_schema.py new file mode 100755 index 000000000000..9eceeba00440 --- /dev/null +++ b/tools/unittests/test_kdoc_test_schema.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0 +""" +Unit=E2=80=91test driver for kernel=E2=80=91doc YAML tests. + +Two kinds of tests are defined: + +* **Schema=E2=80=91validation tests** =E2=80=93 if ``jsonschema`` is avail= able, the + YAML files in this directory are validated against the JSON=E2=80=91Sche= ma + described in ``kdoc-test-schema.yaml``. When the library is not + present, a warning is emitted and the validation step is simply + skipped =E2=80=93 the dynamic kernel=E2=80=91doc tests still run. + +* **Kernel=E2=80=91doc tests** =E2=80=93 dynamically generate one test met= hod per + scenario in ``kdoc-test.yaml``. Each method simply forwards + the data to ``self.run_test`` =E2=80=93 you only need to implement that + helper in your own code. + +File names are kept as module=E2=80=91level constants so that the +implementation stays completely independent of ``pathlib``. +""" + +import os +import sys +import warnings +import yaml +import unittest +from typing import Any, Dict, List + +SRC_DIR =3D os.path.dirname(os.path.realpath(__file__)) +sys.path.insert(0, os.path.join(SRC_DIR, "../lib/python")) + +from unittest_helper import run_unittest + + +# +# Files to read +# +BASE =3D os.path.realpath(os.path.dirname(__file__)) + +SCHEMA_FILE =3D os.path.join(BASE, "kdoc-test-schema.yaml") +TEST_FILE =3D os.path.join(BASE, "kdoc-test.yaml") + +# +# Schema=E2=80=91validation test +# +class TestYAMLSchemaValidation(unittest.TestCase): + """ + Checks if TEST_FILE matches SCHEMA_FILE. + """ + + @classmethod + def setUpClass(cls): + """ + Import jsonschema if available. + """ + + try: + from jsonschema import Draft7Validator + except ImportError: + print("Warning: jsonschema package not available. Skipping sch= ema validation") + cls.validator =3D None + return + + with open(SCHEMA_FILE, encoding=3D"utf-8") as fp: + cls.schema =3D yaml.safe_load(fp) + + cls.validator =3D Draft7Validator(cls.schema) + + def test_kdoc_test_yaml_followsschema(self): + """ + Run jsonschema validation if the validator is available. + If not, emit a warning and return without failing. + """ + if self.validator is None: + return + + with open(TEST_FILE, encoding=3D"utf-8") as fp: + data =3D yaml.safe_load(fp) + + errors =3D self.validator.iter_errors(data) + + msgs =3D [] + for error in errors: + msgs.append(error.message) + + if msgs: + self.fail("Schema validation failed:\n\t" + "\n\t".join(msgs)) + +# -------------------------------------------------------------------- +# Entry point +# -------------------------------------------------------------------- +if __name__ =3D=3D "__main__": + run_unittest(__file__) --=20 2.53.0 From nobody Mon Apr 6 18:53:46 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 14E403A4F48; Wed, 18 Mar 2026 09:11:21 +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=1773825081; cv=none; b=kBJkPJOo6i0+4RE78Vk22lKPJSg/VOkpsjArqIZkltqdl9SbkYgeMrJSOrWlQFz/etL03bXR+GaI12nL2WkS9jCMCwx/Qxf6VkxAFUHP2Ckk3ZkINR6peqqdXNRP9j4oWjgJGy2Jktes1FkNVYNFXu9sppiGeqwEuYoccwlr4r0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773825081; c=relaxed/simple; bh=esMsQCsF6E0nq9eHboKDDqDqJXUEx8Dj6TV/hbIfdWA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=lraD2T/HfWSsW33dfElf+Qv76RG/Tyl0ZgQCSgomM1jsOPHMVxGJhgstMkzW8UhHQTeOrigYcAiTP7yOTGHdhB5uTmiFZ07B3WQ4diAWjFjK1hdPiLeiYeBXpnUYswWZlrmo/n3gXlve4Qg4gfW9vCad3si0p9k77hJyf9mOS38= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=es4ObGoO; 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="es4ObGoO" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7983DC2BCB8; Wed, 18 Mar 2026 09:11:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773825080; bh=esMsQCsF6E0nq9eHboKDDqDqJXUEx8Dj6TV/hbIfdWA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=es4ObGoOsMPBY5FEo1TjRpkECqPYvwaGipLqNWk1BRtqu2RSQjZBrHVxFQ95pM6hG VG3h4Xxpq4VWYqcVzioohy402X3e9Y1coyn8NGlYJfp8sBG6OaEZoeWbBkNyLHsifn MZhHnqFoy45lWaTwQ7OiYCYMG0ShM4UcyeI4lcPNXS11gp9Ehb2KVvt3gan9eLVgm8 +oUcyj8UCJrufNMWz7cDBsptAHS9qg08efZPuOOwTtZCm7Gmuj4B2tdDeM1WWdy2oC BbpNnczSMD/RceiFUsAyTz3bUyL7pQ/3Zg5pzA6A+SRlW3p99SYLLE5pq/H/Pi5RuT pnELJxMbEpqqw== Received: from mchehab by mail.kernel.org with local (Exim 4.99.1) (envelope-from ) id 1w2mvu-00000002fq2-3ELH; Wed, 18 Mar 2026 10:11:18 +0100 From: Mauro Carvalho Chehab To: Jonathan Corbet , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , linux-kernel@vger.kernel.org, Mauro Carvalho Chehab Subject: [PATCH 12/14] docs: test_kdoc_parser: add support for dynamic test creation Date: Wed, 18 Mar 2026 10:11:12 +0100 Message-ID: <7ec2593c5b19de3e3b1d8de92675f6b751d3fa21.1773823995.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.53.0 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-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab Use the content of kdoc-test.yaml to generate unittests to verify that kernel-doc internal methods are parsing C code and generating output the expected way. Depending on what is written at the parser file at kdoc-test.yaml, up to 5 tests can be generated from a single test entry inside the YAML file: 1. from source to kdoc_item: test KernelDoc class; 2. from kdoc_item to man: test ManOutput class; 3. from kdoc_item to rst: test RestOutput class; 4. from source to man without checking expected KdocItem; 5. from source to rst without checking expected KdocItem. Signed-off-by: Mauro Carvalho Chehab --- tools/unittests/test_kdoc_parser.py | 368 ++++++++++++++++++++++++++-- 1 file changed, 350 insertions(+), 18 deletions(-) diff --git a/tools/unittests/test_kdoc_parser.py b/tools/unittests/test_kdo= c_parser.py index 26f74666a000..723dd8c7f4f3 100755 --- a/tools/unittests/test_kdoc_parser.py +++ b/tools/unittests/test_kdoc_parser.py @@ -8,24 +8,43 @@ Unit tests for kernel-doc parser. """ =20 +import logging import os -import unittest import re +import shlex import sys +import unittest =20 from textwrap import dedent from unittest.mock import patch, MagicMock, mock_open =20 +import yaml + SRC_DIR =3D os.path.dirname(os.path.realpath(__file__)) sys.path.insert(0, os.path.join(SRC_DIR, "../lib/python")) =20 -from kdoc.kdoc_parser import KernelDoc +from kdoc.kdoc_files import KdocConfig from kdoc.kdoc_item import KdocItem +from kdoc.kdoc_parser import KernelDoc +from kdoc.kdoc_output import RestFormat, ManFormat + from kdoc.xforms_lists import CTransforms + from unittest_helper import run_unittest =20 + +# +# Test file +# +TEST_FILE =3D os.path.join(SRC_DIR, "kdoc-test.yaml") + +# +# Ancillary logic to clean whitespaces +# #: Regex to help cleaning whitespaces -RE_WHITESPC =3D re.compile(r"\s++") +RE_WHITESPC =3D re.compile(r"[ \t]++") +RE_BEGINSPC =3D re.compile(r"^\s+", re.MULTILINE) +RE_ENDSPC =3D re.compile(r"\s+$", re.MULTILINE) =20 def clean_whitespc(val, relax_whitespace=3DFalse): """ @@ -38,7 +57,9 @@ def clean_whitespc(val, relax_whitespace=3DFalse): if isinstance(val, str): val =3D val.strip() if relax_whitespace: - val =3D RE_WHITESPC.sub("", val) + val =3D RE_WHITESPC.sub(" ", val) + val =3D RE_BEGINSPC.sub("", val) + val =3D RE_ENDSPC.sub("", val) elif isinstance(val, list): val =3D [clean_whitespc(item, relax_whitespace) for item in val] elif isinstance(val, dict): @@ -46,22 +67,59 @@ def clean_whitespc(val, relax_whitespace=3DFalse): return val =20 # -# Helper class to help mocking with +# Helper classes to help mocking with logger and config # -class KdocParser(unittest.TestCase): +class MockLogging(logging.Handler): + """ + Simple class to store everything on a list + """ + + def __init__(self, level=3Dlogging.NOTSET): + super().__init__(level) + self.messages =3D [] + self.formatter =3D logging.Formatter() + + def emit(self, record: logging.LogRecord) -> None: + """ + Append a formatted record to self.messages. + """ + try: + # The `format` method uses the handler's formatter. + message =3D self.format(record) + self.messages.append(message) + except Exception: + self.handleError(record) + +class MockKdocConfig(KdocConfig): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + self.log =3D logging.getLogger(__file__) + self.handler =3D MockLogging() + self.log.addHandler(self.handler) + + def warning(self, msg): + """Ancillary routine to output a warning and increment error count= .""" + + self.log.warning(msg) + +# +# Helper class to generate KdocItem and validate its contents +# +# TODO: check self.config.handler.messages content +# +class GenerateKdocItem(unittest.TestCase): """ Base class to run KernelDoc parser class """ =20 DEFAULT =3D vars(KdocItem("", "", "", 0)) =20 + config =3D MockKdocConfig() + xforms =3D CTransforms() + def setUp(self): self.maxDiff =3D None - self.config =3D MagicMock() - self.config.log =3D MagicMock() - self.config.log.debug =3D MagicMock() - self.xforms =3D CTransforms() - =20 def run_test(self, source, __expected_list, exports=3D{}, fname=3D"tes= t.c", relax_whitespace=3DFalse): @@ -75,6 +133,9 @@ class KdocParser(unittest.TestCase): # Ensure that default values will be there expected_list =3D [] for e in __expected_list: + if not isinstance(e, dict): + e =3D vars(e) + new_e =3D self.DEFAULT.copy() new_e["fname"] =3D fname for key, value in e.items(): @@ -111,13 +172,155 @@ class KdocParser(unittest.TestCase): =20 self.assertEqual(result, value, msg=3Df"at {key}") =20 +# +# Ancillary function that replicates kdoc_files way to generate output +# +def cleanup_timestamp(text): + lines =3D text.split("\n") + + for i, line in enumerate(lines): + if not line.startswith('.TH'): + continue + + parts =3D shlex.split(line) + if len(parts) > 3: + parts[3] =3D "" + + lines[i] =3D " ".join(parts) + + + return "\n".join(lines) + +def gen_output(fname, out_style, symbols, expected, + config=3DNone, relax_whitespace=3DFalse): + """ + Use the output class to return an output content from KdocItem symbols. + """ + + if not config: + config =3D MockKdocConfig() + + out_style.set_config(config) + + msg =3D out_style.output_symbols(fname, symbols) + + result =3D clean_whitespc(msg, relax_whitespace) + result =3D cleanup_timestamp(result) + + expected =3D clean_whitespc(expected, relax_whitespace) + expected =3D cleanup_timestamp(expected) + + return result, expected + +# +# Classes to be used by dynamic test generation from YAML +# +class CToKdocItem(GenerateKdocItem): + def setUp(self): + self.maxDiff =3D None + + def run_parser_test(self, source, symbols, exports, fname): + if isinstance(symbols, dict): + symbols =3D [symbols] + + if isinstance(exports, str): + exports=3Dset([exports]) + elif isinstance(exports, list): + exports=3Dset(exports) + + self.run_test(source, symbols, exports=3Dexports, + fname=3Dfname, relax_whitespace=3DTrue) + +class KdocItemToMan(unittest.TestCase): + out_style =3D ManFormat() + + def setUp(self): + self.maxDiff =3D None + + def run_out_test(self, fname, symbols, expected): + """ + Generate output using out_style, + """ + result, expected =3D gen_output(fname, self.out_style, + symbols, expected) + + self.assertEqual(result, expected) + +class KdocItemToRest(unittest.TestCase): + out_style =3D RestFormat() + + def setUp(self): + self.maxDiff =3D None + + def run_out_test(self, fname, symbols, expected): + """ + Generate output using out_style, + """ + result, expected =3D gen_output(fname, self.out_style, symbols, + expected, relax_whitespace=3DTrue) + + self.assertEqual(result, expected) + + +class CToMan(unittest.TestCase): + out_style =3D ManFormat() + config =3D MockKdocConfig() + xforms =3D CTransforms() + + def setUp(self): + self.maxDiff =3D None + + def run_out_test(self, fname, source, expected): + """ + Generate output using out_style, + """ + patcher =3D patch('builtins.open', + new_callable=3Dmock_open, read_data=3Dsource) + + kernel_doc =3D KernelDoc(self.config, fname, self.xforms) + + with patcher: + export_table, entries =3D kernel_doc.parse_kdoc() + + result, expected =3D gen_output(fname, self.out_style, + entries, expected, config=3Dself.con= fig) + + self.assertEqual(result, expected) + + +class CToRest(unittest.TestCase): + out_style =3D RestFormat() + config =3D MockKdocConfig() + xforms =3D CTransforms() + + def setUp(self): + self.maxDiff =3D None + + def run_out_test(self, fname, source, expected): + """ + Generate output using out_style, + """ + patcher =3D patch('builtins.open', + new_callable=3Dmock_open, read_data=3Dsource) + + kernel_doc =3D KernelDoc(self.config, fname, self.xforms) + + with patcher: + export_table, entries =3D kernel_doc.parse_kdoc() + + result, expected =3D gen_output(fname, self.out_style, entries, + expected, relax_whitespace=3DTrue, + config=3Dself.config) + + self.assertEqual(result, expected) + =20 # -# Selttest class +# Selftest class # -class TestSelfValidate(KdocParser): +class TestSelfValidate(GenerateKdocItem): """ - Tests to check if logic inside KdocParser.run_test() is working. + Tests to check if logic inside GenerateKdocItem.run_test() is working. """ =20 SOURCE =3D """ @@ -147,16 +350,23 @@ class TestSelfValidate(KdocParser): 'Description': 'Does nothing\n\n', 'Return': '\nalways return 0.\n' }, + + 'sections_start_lines': { + 'Description': 4, + 'Return': 7, + }, + + 'parameterdescs': {'arg1': '@arg1 does nothing\n'}, + 'parameterlist': ['arg1'], + 'parameterdesc_start_lines': {'arg1': 3}, + 'parametertypes': {'arg1': 'char *arg1'}, + 'other_stuff': { 'func_macro': False, 'functiontype': 'int', 'purpose': 'Exported function', 'typedef': False }, - 'parameterdescs': {'arg1': '@arg1 does nothing\n'}, - 'parameterlist': ['arg1'], - 'parameterdesc_start_lines': {'arg1': 3}, - 'parametertypes': {'arg1': 'char *arg1'}, }] =20 EXPORTS =3D {"function3"} @@ -195,6 +405,128 @@ class TestSelfValidate(KdocParser): """ self.run_test(self.SOURCE, [self.DEFAULT.copy()], self.EXPORTS) =20 +# +# Class and logic to create dynamic tests from YAML +# + +class KernelDocDynamicTests(): + """ + Dynamically create a set of tests from a YAML file. + """ + + @classmethod + def create_parser_test(cls, name, fname, source, symbols, exports): + """ + Return a function that will be attached to the test class. + """ + def test_method(self): + """Lambda-like function to run tests with provided vars""" + self.run_parser_test(source, symbols, exports, fname) + + test_method.__name__ =3D f"test_gen_{name}" + + setattr(CToKdocItem, test_method.__name__, test_method) + + @classmethod + def create_out_test(cls, name, fname, symbols, out_type, data): + """ + Return a function that will be attached to the test class. + """ + def test_method(self): + """Lambda-like function to run tests with provided vars""" + self.run_out_test(fname, symbols, data) + + test_method.__name__ =3D f"test_{out_type}_{name}" + + if out_type =3D=3D "man": + setattr(KdocItemToMan, test_method.__name__, test_method) + else: + setattr(KdocItemToRest, test_method.__name__, test_method) + + @classmethod + def create_src2out_test(cls, name, fname, source, out_type, data): + """ + Return a function that will be attached to the test class. + """ + def test_method(self): + """Lambda-like function to run tests with provided vars""" + self.run_out_test(fname, source, data) + + test_method.__name__ =3D f"test_{out_type}_{name}" + + if out_type =3D=3D "man": + setattr(CToMan, test_method.__name__, test_method) + else: + setattr(CToRest, test_method.__name__, test_method) + + @classmethod + def create_tests(cls): + """ + Iterate over all scenarios and add a method to the class for each. + + The logic in this function assumes a valid test that are compliant + with kdoc-test-schema.yaml. There is an unit test to check that. + As such, it picks mandatory values directly, and uses get() for the + optional ones. + """ + + with open(TEST_FILE, encoding=3D"utf-8") as fp: + testset =3D yaml.safe_load(fp) + + tests =3D testset["tests"] + + for idx, test in enumerate(tests): + name =3D test["name"] + fname =3D test["fname"] + source =3D test["source"] + expected_list =3D test["expected"] + + exports =3D test.get("exports", []) + + # + # The logic below allows setting up to 5 types of test: + # 1. from source to kdoc_item: test KernelDoc class; + # 2. from kdoc_item to man: test ManOutput class; + # 3. from kdoc_item to rst: test RestOutput class; + # 4. from source to man without checking expected KdocItem; + # 5. from source to rst without checking expected KdocItem. + # + for expected in expected_list: + kdoc_item =3D expected.get("kdoc_item") + man =3D expected.get("man", []) + rst =3D expected.get("rst", []) + + if kdoc_item: + if isinstance(kdoc_item, dict): + kdoc_item =3D [kdoc_item] + + symbols =3D [] + + for arg in kdoc_item: + arg["fname"] =3D fname + arg["start_line"] =3D 1 + + symbols.append(KdocItem.from_dict(arg)) + + if source: + cls.create_parser_test(name, fname, source, + symbols, exports) + + if man: + cls.create_out_test(name, fname, symbols, "man", m= an) + + if rst: + cls.create_out_test(name, fname, symbols, "rst", r= st) + + elif source: + if man: + cls.create_src2out_test(name, fname, source, "man"= , man) + + if rst: + cls.create_src2out_test(name, fname, source, "rst"= , rst) + +KernelDocDynamicTests.create_tests() + # # Run all tests # --=20 2.53.0 From nobody Mon Apr 6 18:53:46 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 1C5C83A5E8F; Wed, 18 Mar 2026 09:11:21 +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=1773825081; cv=none; b=MDSc/Yatm6a86LfQmYiEoIrmWBK9v9bEhuYHX3rZPVGvfOP5ImAYZf6rimOzvSL5ub+lhrWO9JMwQMuGg1ljA5MdbVBCmRBqndbKGX1DbTiS8lDcsyOFONnYramVWHlbht7wmDFFUowRXCnxbjwi3JPqhJTQnYG1yb4xFmOaj6E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773825081; c=relaxed/simple; bh=x+z0BOd8CUTKW/M8RsgH8506TTiWFSWuiqgXODs0fGQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=n3H6H9YC7yBZ/BDZ4ERrygdjoyuYlOBRAIdGoYWeLncFQ9gxd/lp0XPpPaAfCZzSCRWulLieuegaXqkC4819A6p7nK7rhpXAtYmQyHCKj4Ira+5iY/JMlmtg8zz6fFjTDHONQGQF19GVx81bqISgHld3NBR401MhUwKFkpHf5Q0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=QMA3nYgB; 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="QMA3nYgB" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 80C10C2BCF7; Wed, 18 Mar 2026 09:11:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773825080; bh=x+z0BOd8CUTKW/M8RsgH8506TTiWFSWuiqgXODs0fGQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QMA3nYgBKJOTGvhxKjIExIXFbLCffxkYWyKPm8RVzJV+en4VbXAzioz2F7lZ0WCHS ftEsT3K+CVvZtx48yOGD7zIo6BhR2o4iS17aJ2IA+Aj5s/ilTCklugoI40yr9kWJMc 2nU4mV7NtV8FRVFEGaJ9m61RqXRi6alrgYCD+LvNJAqJPbUUwnUt0Zemtmk1wDoGrJ 5IrOIkVmSHDXUEikq0ixFrtScY3QSBGP0SvljeVlCQr0tMp9wfYlWuqTRF7ciVmkox 7fhMk9VMCwu7FLECSnmBuzqTsQYBxnmxPBUDyKZdkcR3i4EZ0s7Q7eYOTjYkZPUops mqPCrhgKYTKmg== Received: from mchehab by mail.kernel.org with local (Exim 4.99.1) (envelope-from ) id 1w2mvu-00000002fq6-3LVu; Wed, 18 Mar 2026 10:11:18 +0100 From: Mauro Carvalho Chehab To: Jonathan Corbet , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , linux-kernel@vger.kernel.org, Mauro Carvalho Chehab Subject: [PATCH 13/14] docs: add a new file to write kernel-doc output to a YAML file Date: Wed, 18 Mar 2026 10:11:13 +0100 Message-ID: <5d084ca1a91f6a620534a1135d1b8183d934319a.1773823995.git.mchehab+huawei@kernel.org> X-Mailer: git-send-email 2.53.0 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-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab Storing kernel-doc output is helpful to allow debugging problems on it and to preparate unit tests. Add a class to store such contents at the same format as defined at kdoc-test-schema.yaml. Signed-off-by: Mauro Carvalho Chehab --- tools/lib/python/kdoc/kdoc_yaml_file.py | 155 ++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 tools/lib/python/kdoc/kdoc_yaml_file.py diff --git a/tools/lib/python/kdoc/kdoc_yaml_file.py b/tools/lib/python/kdo= c/kdoc_yaml_file.py new file mode 100644 index 000000000000..db131503c3f6 --- /dev/null +++ b/tools/lib/python/kdoc/kdoc_yaml_file.py @@ -0,0 +1,155 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0 +# Copyright(c) 2026: Mauro Carvalho Chehab . + +import os + +from kdoc.kdoc_output import ManFormat, RestFormat + + +class KDocTestFile(): + """ + Handles the logic needed to store kernel=E2=80=91doc output inside a Y= AML file. + Useful for unit tests and regression tests. + """ + + def __init__(self, config, yaml_file, yaml_content): + # + # Bail out early if yaml is not available + # + try: + import yaml + except ImportError: + sys.exit("Warning: yaml package not available. Aborting it.") + + self.config =3D config + self.test_file =3D os.path.expanduser(yaml_file) + self.yaml_content =3D yaml_content + + self.tests =3D [] + + out_dir =3D os.path.dirname(self.test_file) + if out_dir and not os.path.isdir(out_dir): + sys.exit(f"Directory {out_dir} doesn't exist.") + + self.out_style =3D [] + + if "man" in self.yaml_content: + out_style =3D ManFormat() + out_style.set_config(self.config) + + self.out_style.append(out_style) + + if "rst" in self.yaml_content: + out_style =3D RestFormat() + out_style.set_config(self.config) + + self.out_style.append(out_style) + + def set_filter(self, export, internal, symbol, nosymbol, + function_table, enable_lineno, no_doc_sections): + """ + Set filters at the output classes. + """ + for out_style in self.out_style: + out_style.set_filter(export, internal, symbol, + nosymbol, function_table, + enable_lineno, no_doc_sections) + + @staticmethod + def get_kdoc_item(arg, start_line=3D1): + + d =3D vars(arg) + + declaration_start_line =3D d.get("declaration_start_line") + if not declaration_start_line: + return d + + d["declaration_start_line"] =3D start_line + + parameterdesc_start_lines =3D d.get("parameterdesc_start_lines") + if parameterdesc_start_lines: + for key in parameterdesc_start_lines: + ln =3D parameterdesc_start_lines[key] + ln +=3D start_line - declaration_start_line + + parameterdesc_start_lines[key] =3D ln + + sections_start_lines =3D d.get("sections_start_lines") + if sections_start_lines: + for key in sections_start_lines: + ln =3D sections_start_lines[key] + ln +=3D start_line - declaration_start_line + + sections_start_lines[key] =3D ln + + return d + + def output_symbols(self, fname, symbols, source): + """ + Store source, symbols and output strings at self.tests. + """ + + # + # KdocItem needs to be converted into dicts + # + kdoc_item =3D [] + expected =3D [] + + if not symbols and not source: + return + + if not source or len(symbols) !=3D len(source): + print(f"Warning: lengths are different. Ignoring {fname}") + + # Folding without line numbers is too hard. + # The right thing to do here to proceed would be to delete + # not-handled source blocks, as len(source) should be bigger + # than len(symbols) + return + + base_name =3D "test_" + fname.replace(".", "_").replace("/", "_") + expected_dict =3D {} + start_line=3D1 + + for i in range(0, len(symbols)): + arg =3D symbols[i] + + if "KdocItem" in self.yaml_content: + msg =3D self.get_kdoc_item(arg) + + expected_dict["kdoc_item"] =3D msg + + for out_style in self.out_style: + if isinstance(out_style, ManFormat): + key =3D "man" + else: + key =3D "rst" + + expected_dict[key]=3D out_style.output_symbols(fname, [arg= ]) + + name =3D f"{base_name}_{i:03d}" + + test =3D { + "name": name, + "description": f"{fname} line {source[i]["ln"]}", + "fname": fname, + "source": source[i]["data"], + "expected": [expected_dict] + } + + self.tests.append(test) + + expected_dict =3D {} + + def write(self): + """ + Output the content of self.tests to self.test_file. + """ + import yaml + + data =3D {"tests": self.tests} + + with open(self.test_file, "w", encoding=3D"utf-8") as fp: + yaml.safe_dump(data, fp, sort_keys=3DFalse, default_style=3D"|= ", + default_flow_style=3DFalse, allow_unicode=3DTru= e) --=20 2.53.0 From nobody Mon Apr 6 18:53:46 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 104983A1A55; Wed, 18 Mar 2026 09:11:21 +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=1773825081; cv=none; b=sYQslGZuHknMh8gdNRSXtThEFsMGbcRPqMdCQkkNMGljRhnuIeLhWNCmyJ4aE+gvHi0duWoXNsMuRBcaVGCfYccfZXeHoh/8QDmWgoFC2z/j7cUO5Zjpa+ciy+sMpxn62CfD3oYJUXkXQ/D62ns8LxjuIIIfH3CSvW6ADLhwzpI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773825081; c=relaxed/simple; bh=scL+K6GSvLApr7G1/Af3VPGVcWpWnw78ruddz9ClsaI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=RSrsjn3Jw+d30v7fks95Ut9xgkuHNunHxkKP2c+tSlbG1xIj+mXYKiTwJIvMIrbU6n7ezziE0+5qpAxVs/CLvBn8RgwHSWJHg6ulYLp/AdrjiDH3wb+EG/GkgbzG2/jiMNZ3sU1b6Q0oUQXvp0i95JuXc+qPLNPOgv7awZ8r00c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=kKjY/H39; 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="kKjY/H39" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 89D99C4AF0C; Wed, 18 Mar 2026 09:11:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1773825080; bh=scL+K6GSvLApr7G1/Af3VPGVcWpWnw78ruddz9ClsaI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kKjY/H39l9jiKmSMDtZK788cFtVzTVP38/JwHMYZEl6FQVOLLTQs8xmX9+NXFQBSO mmvdYFSF4X8XgKQbnerfrtCSt4XZUtLFl6OFsbbp2JVxJI+cR0vjoXz/mvDQoxSJzN +CIClbJPwXZeRkXiT5cqBhY3E2ZGph/eE+6f02d3X+W67oJcgshilK0GeMXa52O79u oXjwNh+QXfBxzUcRX5IjOnrzKWqwOes37T3iqAm6efwNWKj3yAqqGwERr8MrF7Lm22 xXItJRCG6rEDYUnClV6SSbEpYii8wAkxBmlwkgn4w8ia+S/CMs+pt3ku4mmWDlrsHg INJva+tyh/wLA== Received: from mchehab by mail.kernel.org with local (Exim 4.99.1) (envelope-from ) id 1w2mvu-00000002fqA-3ScD; Wed, 18 Mar 2026 10:11:18 +0100 From: Mauro Carvalho Chehab To: Jonathan Corbet , Linux Doc Mailing List Cc: Mauro Carvalho Chehab , linux-kernel@vger.kernel.org, Aleksandr Loktionov , Mauro Carvalho Chehab , Randy Dunlap , Shuah Khan Subject: [PATCH 14/14] docs: kernel-doc: add support to store output on a YAML file Date: Wed, 18 Mar 2026 10:11:14 +0100 Message-ID: X-Mailer: git-send-email 2.53.0 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-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab Add a command line parameter and library support to optionally store: - KdocItem intermediate format after parsing; - man pages output; - rst output. inside a YAML file. Signed-off-by: Mauro Carvalho Chehab --- tools/docs/kernel-doc | 48 +++++++++++++++++++++++----- tools/lib/python/kdoc/kdoc_files.py | 47 +++++++++++++++++++++++---- tools/lib/python/kdoc/kdoc_parser.py | 27 +++++++++++++++- 3 files changed, 107 insertions(+), 15 deletions(-) diff --git a/tools/docs/kernel-doc b/tools/docs/kernel-doc index 3a932f95bdf5..d9192c3f1645 100755 --- a/tools/docs/kernel-doc +++ b/tools/docs/kernel-doc @@ -240,11 +240,9 @@ def main(): help=3DEXPORT_FILE_DESC) =20 # - # Output format mutually-exclusive group + # Output format # - out_group =3D parser.add_argument_group("Output format selection (mutu= ally exclusive)") - - out_fmt =3D out_group.add_mutually_exclusive_group() + out_fmt =3D parser.add_argument_group("Output format selection (mutual= ly exclusive)") =20 out_fmt.add_argument("-m", "-man", "--man", action=3D"store_true", help=3D"Output troff manual page format.") @@ -253,6 +251,12 @@ def main(): out_fmt.add_argument("-N", "-none", "--none", action=3D"store_true", help=3D"Do not output documentation, only warning= s.") =20 + out_fmt.add_argument("-y", "--yaml-file", "--yaml", + help=3D"Stores kernel-doc output on a yaml file.") + out_fmt.add_argument("-k", "--kdoc-item", "--kdoc", action=3D"store_tr= ue", + help=3D"Store KdocItem inside yaml file. Ued toge= ther with --yaml.") + + # # Output selection mutually-exclusive group # @@ -323,14 +327,42 @@ def main(): from kdoc.kdoc_files import KernelFiles # pylint: disable= =3DC0415 from kdoc.kdoc_output import RestFormat, ManFormat # pylint: disable= =3DC0415 =20 - if args.man: - out_style =3D ManFormat(modulename=3Dargs.modulename) - elif args.none: + yaml_content =3D set() + if args.yaml_file: out_style =3D None + + if args.man: + yaml_content |=3D {"man"} + + if args.rst: + yaml_content |=3D {"rst"} + + if args.kdoc_item or not yaml_content: + yaml_content |=3D {"KdocItem"} + else: - out_style =3D RestFormat() + n_outputs =3D 0 + + if args.man: + out_style =3D ManFormat(modulename=3Dargs.modulename) + n_outputs +=3D 1 + + if args.none: + out_style =3D None + n_outputs +=3D 1 + + if args.rst or n_outputs =3D=3D 0: + n_outputs +=3D 1 + out_style =3D RestFormat() + + if n_outputs > 1: + parser.error("Those arguments are muttually exclusive: --man,= --rst, --none, except when generating a YAML file.") + + elif not n_outputs: + out_style =3D RestFormat() =20 kfiles =3D KernelFiles(verbose=3Dargs.verbose, + yaml_file=3Dargs.yaml_file, yaml_content=3Dyaml_c= ontent, out_style=3Dout_style, werror=3Dargs.werror, wreturn=3Dargs.wreturn, wshort_desc=3Dargs.wshort= _desc, wcontents_before_sections=3Dargs.wcontents_before= _sections) diff --git a/tools/lib/python/kdoc/kdoc_files.py b/tools/lib/python/kdoc/kd= oc_files.py index 58f4ee08e226..5a299ed44d62 100644 --- a/tools/lib/python/kdoc/kdoc_files.py +++ b/tools/lib/python/kdoc/kdoc_files.py @@ -16,6 +16,7 @@ import re from kdoc.kdoc_parser import KernelDoc from kdoc.xforms_lists import CTransforms from kdoc.kdoc_output import OutputFormat +from kdoc.kdoc_yaml_file import KDocTestFile =20 =20 class GlobSourceFiles: @@ -152,6 +153,12 @@ class KernelFiles(): =20 If not specified, defaults to use: ``logging.getLogger("kernel-doc= ")`` =20 + ``yaml_file`` + If defined, stores the output inside a YAML file. + + ``yaml_content`` + Defines what will be inside the YAML file. + Note: There are two type of parsers defined here: =20 @@ -181,7 +188,12 @@ class KernelFiles(): if fname in self.files: return =20 - doc =3D KernelDoc(self.config, fname, self.xforms) + if self.test_file: + store_src =3D True + else: + store_src =3D False + + doc =3D KernelDoc(self.config, fname, self.xforms, store_src=3Dsto= re_src) export_table, entries =3D doc.parse_kdoc() =20 self.export_table[fname] =3D export_table @@ -191,6 +203,10 @@ class KernelFiles(): =20 self.results[fname] =3D entries =20 + source =3D doc.get_source() + if source: + self.source[fname] =3D source + def process_export_file(self, fname): """ Parses ``EXPORT_SYMBOL*`` macros from a single Kernel source file. @@ -220,7 +236,7 @@ class KernelFiles(): def __init__(self, verbose=3DFalse, out_style=3DNone, xforms=3DNone, werror=3DFalse, wreturn=3DFalse, wshort_desc=3DFalse, wcontents_before_sections=3DFalse, - logger=3DNone): + yaml_file=3DNone, yaml_content=3DNone, logger=3DNone): """ Initialize startup variables and parse all files. """ @@ -259,6 +275,11 @@ class KernelFiles(): # Override log warning, as we want to count errors self.config.warning =3D self.warning =20 + if yaml_file: + self.test_file =3D KDocTestFile(self.config, yaml_file, yaml_c= ontent) + else: + self.test_file =3D None + if xforms: self.xforms =3D xforms else: @@ -273,6 +294,7 @@ class KernelFiles(): =20 self.errors =3D 0 self.results =3D {} + self.source =3D {} =20 self.files =3D set() self.export_files =3D set() @@ -331,16 +353,29 @@ class KernelFiles(): for s in symbol: function_table.add(s) =20 - self.out_style.set_filter(export, internal, symbol, nosymbol, - function_table, enable_lineno, - no_doc_sections) - if fname not in self.results: self.config.log.warning("No kernel-doc for file %s", fname) continue =20 symbols =3D self.results[fname] =20 + if self.test_file: + self.test_file.set_filter(export, internal, symbol, nosymb= ol, + function_table, enable_lineno, + no_doc_sections) + + self.test_file.output_symbols(fname, symbols, + self.source.get(fname)) + + continue + + self.out_style.set_filter(export, internal, symbol, nosymbol, + function_table, enable_lineno, + no_doc_sections) + msg =3D self.out_style.output_symbols(fname, symbols) if msg: yield fname, msg + + if self.test_file: + self.test_file.write() diff --git a/tools/lib/python/kdoc/kdoc_parser.py b/tools/lib/python/kdoc/k= doc_parser.py index 35658a7e72d5..a10e64589d76 100644 --- a/tools/lib/python/kdoc/kdoc_parser.py +++ b/tools/lib/python/kdoc/kdoc_parser.py @@ -246,12 +246,13 @@ class KernelDoc: #: String to write when a parameter is not described. undescribed =3D "-- undescribed --" =20 - def __init__(self, config, fname, xforms): + def __init__(self, config, fname, xforms, store_src=3DFalse): """Initialize internal variables""" =20 self.fname =3D fname self.config =3D config self.xforms =3D xforms + self.store_src =3D store_src =20 tokenizer_set_log(self.config.log, f"{self.fname}: CMatch: ") =20 @@ -264,6 +265,9 @@ class KernelDoc: # Place all potential outputs into an array self.entries =3D [] =20 + # When store_src is true, the kernel-doc source content is stored = here + self.source =3D None + # # We need Python 3.7 for its "dicts remember the insertion # order" guarantee @@ -1592,6 +1596,15 @@ class KernelDoc: state.DOCBLOCK: process_docblock, } =20 + def get_source(self): + """ + Return the file content of the lines handled by kernel-doc at the + latest parse_kdoc() run. + + Returns none if KernelDoc() was not initialized with store_src, + """ + return self.source + def parse_kdoc(self): """ Open and process each line of a C source file. @@ -1605,6 +1618,8 @@ class KernelDoc: prev =3D "" prev_ln =3D None export_table =3D set() + self.source =3D [] + self.state =3D state.NORMAL =20 try: with open(self.fname, "r", encoding=3D"utf8", @@ -1631,6 +1646,8 @@ class KernelDoc: ln, state.name[self.state], line) =20 + prev_state =3D self.state + # This is an optimization over the original script. # There, when export_file was used for the same file, # it was read twice. Here, we use the already-existing @@ -1641,6 +1658,14 @@ class KernelDoc: # Hand this line to the appropriate state handler self.state_actions[self.state](self, ln, line) =20 + if self.store_src and prev_state !=3D self.state or se= lf.state !=3D state.NORMAL: + if self.state =3D=3D state.NAME: + # A "/**" was detected. Add a new source eleme= nt + self.source.append({"ln": ln, "data": line + "= \n"}) + else: + # Append to the existing one + self.source[-1]["data"] +=3D line + "\n" + self.emit_unused_warnings() =20 except OSError: --=20 2.53.0