mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: 闲逛 <2368492046@qq.com>
To: corbet <corbet@lwn.net>, mchehab <mchehab@kernel.org>
Cc: wy <wy@wyuan.org>, linux-doc <linux-doc@vger.kernel.org>,
	skhan <skhan@linuxfoundation.org>,
	rdunlap <rdunlap@infradead.org>,
	linux-kernel <linux-kernel@vger.kernel.org>
Subject: [PATCH v2 2/4] docs: kernel-doc: combine input and additional export sources
Date: Sat, 14 Nov 2026 17:06:29 +0800	[thread overview]
Message-ID: <tencent_ED2B23FDEEE634765DB55BC98D0DB34D2B08@qq.com> (raw)

From: yuehua-meng <2368492046@qq.com>

With multiple inputs, msg() defaults the export source to the first
filename and reuses it for later files. An explicit -export-file instead
excludes exports from the input files, despite the CLI documenting it as
an additional source. Relative SRCTREE paths are also resolved twice when
the already resolved input filenames pass through GlobSourceFiles again.

Build the export filter once from the cached input filenames and the
resolved additional export files. This preserves exports from both kinds
of source without adding SRCTREE a second time, and avoids rebuilding the
same set for every input. Keep explicit symbol selection in the same set.

Add CLI regressions for multiple input files, declarations exported by a
different input, additional export sources, and relative SRCTREE paths.

Fixes: 16740c29dbf3 ("scripts/kernel_doc.py: better handle exported symbols")

Signed-off-by: yuehua-meng <2368492046@qq.com>
---
Changes in v2:
Include exports from both inputs and additional export files. Avoid
resolving relative SRCTREE paths twice and compute the filter once.
Add regressions for those combinations and cross-file declarations.

 tools/lib/python/kdoc/kdoc_files.py  | 21 +++-----
 tools/unittests/test_kdoc_exports.py | 79 ++++++++++++++++++++++++++++
 2 files changed, 87 insertions(+), 13 deletions(-)
 create mode 100644 tools/unittests/test_kdoc_exports.py

diff --git a/tools/lib/python/kdoc/kdoc_files.py b/tools/lib/python/kdoc/kdoc_files.py
index d39b15edd..0118470aa 100644
--- a/tools/lib/python/kdoc/kdoc_files.py
+++ b/tools/lib/python/kdoc/kdoc_files.py
@@ -339,20 +339,15 @@ class KernelFiles():
 
         glob = GlobSourceFiles(srctree=self.config.src_tree)
 
-        for fname in filenames:
-            function_table = set()
-
-            if internal or export:
-                if not export_file:
-                    export_file = [fname]
-
-                for f in glob.parse_files(export_file, self.file_not_found_cb):
-                    function_table |= self.export_table[f]
-
-            if symbol:
-                for s in symbol:
-                    function_table.add(s)
+        function_table = set(symbol or ())
+        if internal or export:
+            export_sources = set(filenames)
+            export_sources.update(glob.parse_files(export_file,
+                                                  self.file_not_found_cb))
+            for f in export_sources:
+                function_table.update(self.export_table.get(f, ()))
 
+        for fname in filenames:
             if fname not in self.results:
                 self.config.log.warning("No kernel-doc for file %s", fname)
                 continue
diff --git a/tools/unittests/test_kdoc_exports.py b/tools/unittests/test_kdoc_exports.py
new file mode 100644
index 000000000..5bd38d164
--- /dev/null
+++ b/tools/unittests/test_kdoc_exports.py
@@ -0,0 +1,79 @@
+# SPDX-License-Identifier: GPL-2.0
+"""Regression tests for kernel-doc's multi-file export selection."""
+
+from kdoc_cli_helper import KernelDocCliTest
+
+
+class TestKernelDocExports(KernelDocCliTest):
+    def setUp(self):
+        super().setUp()
+        self.files = []
+        for name in ("alpha", "beta"):
+            self.files.append(self.source(name + ".c", (
+                f"/**\n * {name} - example function\n */\n"
+                f"void {name}(void) {{}}\nEXPORT_SYMBOL({name});\n"
+            )))
+
+    def test_exports_from_all_inputs(self):
+        result = self.run_kdoc("-export", *self.files)
+        self.assertEqual(result.returncode, 0, result.stderr)
+        self.assertIn("void alpha", result.stdout)
+        self.assertIn("void beta", result.stdout)
+
+    def test_internal_excludes_all_exports(self):
+        result = self.run_kdoc("-internal", *self.files)
+        self.assertEqual(result.returncode, 0, result.stderr)
+        self.assertEqual(result.stdout.strip(), "")
+
+    def test_unfiltered_output(self):
+        result = self.run_kdoc(*self.files)
+        self.assertEqual(result.returncode, 0, result.stderr)
+        self.assertIn("void alpha", result.stdout)
+        self.assertIn("void beta", result.stdout)
+
+    def test_additional_exports_preserve_input_exports(self):
+        header = self.source("extra.h", (
+            "/**\n * gamma - externally exported function\n */\n"
+            "void gamma(void);\n"
+            "/**\n * delta - internal function\n */\n"
+            "void delta(void);\n"
+        ))
+        exports = self.source("exports.c", "EXPORT_SYMBOL(gamma);\n")
+        for mode in ("-export", "-internal"):
+            with self.subTest(mode=mode):
+                result = self.run_kdoc(mode, "-export-file", exports,
+                                       *self.files, header)
+                self.assertEqual(result.returncode, 0, result.stderr)
+                for name in ("alpha", "beta", "gamma"):
+                    if mode == "-export":
+                        self.assertIn("void " + name, result.stdout)
+                    else:
+                        self.assertNotIn("void " + name, result.stdout)
+                if mode == "-export":
+                    self.assertNotIn("void delta", result.stdout)
+                else:
+                    self.assertIn("void delta", result.stdout)
+
+    def test_relative_srctree(self):
+        sources = self.directory / "sources"
+        sources.mkdir()
+        self.source("sources/example.c", (
+            "/**\n * example - exported function\n */\n"
+            "void example(void) {}\nEXPORT_SYMBOL(example);\n"
+        ))
+        result = self.run_kdoc("-export", "example.c",
+                               environment={"SRCTREE": "sources"},
+                               cwd=self.directory)
+        self.assertEqual(result.returncode, 0, result.stderr)
+        self.assertEqual(result.stderr, "")
+        self.assertIn("void example", result.stdout)
+
+    def test_export_from_another_input(self):
+        header = self.source("example.h", (
+            "/**\n * example - declaration exported from another input\n */\n"
+            "void example(void);\n"
+        ))
+        source = self.source("example.c", "EXPORT_SYMBOL(example);\n")
+        result = self.run_kdoc("-export", header, source)
+        self.assertEqual(result.returncode, 0, result.stderr)
+        self.assertIn("void example", result.stdout)
-- 
2.53.0.windows.2


                 reply	other threads:[~2026-11-14  9:06 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=tencent_ED2B23FDEEE634765DB55BC98D0DB34D2B08@qq.com \
    --to=2368492046@qq.com \
    --cc=corbet@lwn.net \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mchehab@kernel.org \
    --cc=rdunlap@infradead.org \
    --cc=skhan@linuxfoundation.org \
    --cc=wy@wyuan.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®