* [PATCH] docs: kdoc_output: don't add a man page tail for filtered-out symbols
@ 2026-09-29 13:36 Simon Sudarushkin via B4 Relay
2026-09-30 0:29 ` Randy Dunlap
0 siblings, 1 reply; 2+ messages in thread
From: Simon Sudarushkin via B4 Relay @ 2026-09-29 13:36 UTC (permalink / raw)
To: Jonathan Corbet, Shuah Khan, Randy Dunlap, Mauro Carvalho Chehab
Cc: Mauro Carvalho Chehab, linux-doc, linux-kernel, Simon Sudarushkin
From: Simon Sudarushkin <simonsudarushkin@gmail.com>
ManFormat.msg() appends the "SEE ALSO" tail after every call to the base
class msg(), even when the -e, -i, -s or --nosymbol filters dropped the
symbol and nothing was written for it. With -s, every other symbol in
the file leaves a stray "SEE ALSO" block behind the requested page. With
-e on a file that exports nothing, the output is only such blocks, with
no .TH header at all:
$ tools/docs/kernel-doc -man -s string_get_size lib/string_helpers.c \
| grep -c 'SEE ALSO'
13
$ tools/docs/kernel-doc -man -e include/rdma/ib_mad.h | grep -c '^\.TH'
0
Only add the tail when the base class produced a page, and add unit
tests for both cases.
Reported-by: Randy Dunlap <rdunlap@infradead.org>
Closes: https://lore.kernel.org/all/fc7978bb-a71f-456d-84bb-670c8f0426ed@infradead.org/
Fixes: 104e0a682e12 ("tools: kernel-doc: add a see also section at man pages")
Assisted-by: LLM
Signed-off-by: Simon Sudarushkin <simonsudarushkin@gmail.com>
---
Randy, this takes a different route from your patch in August [1]: the
out_tail() call stays in ManFormat.msg() and is skipped when the base
class produced no page, so OutputFormat does not need to know about it.
DOC blocks that are shown keep their tail, since they get their own .TH.
[1] https://lore.kernel.org/all/20260816054826.3988516-1-rdunlap@infradead.org/
---
tools/lib/python/kdoc/kdoc_output.py | 5 +++-
tools/unittests/test_kdoc_parser.py | 52 ++++++++++++++++++++++++++++++++++++
2 files changed, 56 insertions(+), 1 deletion(-)
diff --git a/tools/lib/python/kdoc/kdoc_output.py b/tools/lib/python/kdoc/kdoc_output.py
index 618b0d765ef5..659a2c6fb6be 100644
--- a/tools/lib/python/kdoc/kdoc_output.py
+++ b/tools/lib/python/kdoc/kdoc_output.py
@@ -763,7 +763,10 @@ class ManFormat(OutputFormat):
Add a tail at the end of man pages output.
"""
super().msg(fname, name, args)
- self.out_tail(fname, name, args)
+
+ # Symbols dropped by the output filters produce no page
+ if self.data:
+ self.out_tail(fname, name, args)
return self.data
diff --git a/tools/unittests/test_kdoc_parser.py b/tools/unittests/test_kdoc_parser.py
index c4a76ed13dbc..bcb1b1a5ccc6 100755
--- a/tools/unittests/test_kdoc_parser.py
+++ b/tools/unittests/test_kdoc_parser.py
@@ -301,6 +301,58 @@ class CToMan(unittest.TestCase):
self.assertEqual(result, expected)
+class ManFilterTail(unittest.TestCase):
+ """
+ Symbols dropped by the output filters must not leave a man page tail.
+ """
+
+ source = dedent("""
+ /**
+ * foo - First function
+ * @a: an argument
+ */
+ int foo(int a) { return 0; };
+
+ /**
+ * bar - Second function
+ * @b: an argument
+ */
+ int bar(int b) { return 0; };
+ """)
+
+ def setUp(self):
+ config = MockKdocConfig()
+ kernel_doc = KernelDoc(config, "mock.c", CTransforms())
+
+ with patch('builtins.open', new_callable=mock_open,
+ read_data=self.source):
+ _, self.entries = kernel_doc.parse_kdoc()
+
+ self.out_style = ManFormat()
+ self.out_style.set_config(config)
+
+ def run_filter(self, **kwargs):
+ args = {"export": False, "internal": False, "symbol": None,
+ "nosymbol": None, "function_table": set(),
+ "enable_lineno": False, "no_doc_sections": False}
+ args.update(kwargs)
+
+ self.out_style.set_filter(**args)
+
+ return self.out_style.output_symbols("mock.c", self.entries)
+
+ def test_symbol_filter(self):
+ """Only the selected symbol gets a page, with a single tail."""
+ result = self.run_filter(symbol=["foo"], function_table={"foo"})
+
+ self.assertEqual(result.count(".TH "), 1)
+ self.assertEqual(result.count('.SH "SEE ALSO"'), 1)
+
+ def test_all_filtered_out(self):
+ """No exported symbols: no output at all."""
+ self.assertEqual(self.run_filter(export=True), "")
+
+
class CToRest(unittest.TestCase):
out_style = RestFormat()
config = MockKdocConfig()
---
base-commit: 4f041d7b65b8007403cce30ecf69ad42d48ec315
change-id: 20260929-kdoc-man-filter-eba1ff857dad
Best regards,
--
Simon Sudarushkin <simonsudarushkin@gmail.com>
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] docs: kdoc_output: don't add a man page tail for filtered-out symbols
2026-09-29 13:36 [PATCH] docs: kdoc_output: don't add a man page tail for filtered-out symbols Simon Sudarushkin via B4 Relay
@ 2026-09-30 0:29 ` Randy Dunlap
0 siblings, 0 replies; 2+ messages in thread
From: Randy Dunlap @ 2026-09-30 0:29 UTC (permalink / raw)
To: simonsudarushkin, Jonathan Corbet, Shuah Khan, Mauro Carvalho Chehab
Cc: Mauro Carvalho Chehab, linux-doc, linux-kernel
Hi Simon,
On 9/29/26 6:36 AM, Simon Sudarushkin via B4 Relay wrote:
> From: Simon Sudarushkin <simonsudarushkin@gmail.com>
>
> ManFormat.msg() appends the "SEE ALSO" tail after every call to the base
> class msg(), even when the -e, -i, -s or --nosymbol filters dropped the
> symbol and nothing was written for it. With -s, every other symbol in
> the file leaves a stray "SEE ALSO" block behind the requested page. With
> -e on a file that exports nothing, the output is only such blocks, with
> no .TH header at all:
>
> $ tools/docs/kernel-doc -man -s string_get_size lib/string_helpers.c \
> | grep -c 'SEE ALSO'
> 13
> $ tools/docs/kernel-doc -man -e include/rdma/ib_mad.h | grep -c '^\.TH'
> 0
>
> Only add the tail when the base class produced a page, and add unit
> tests for both cases.
>
> Reported-by: Randy Dunlap <rdunlap@infradead.org>
> Closes: https://lore.kernel.org/all/fc7978bb-a71f-456d-84bb-670c8f0426ed@infradead.org/
> Fixes: 104e0a682e12 ("tools: kernel-doc: add a see also section at man pages")
> Assisted-by: LLM
> Signed-off-by: Simon Sudarushkin <simonsudarushkin@gmail.com>
> ---
> Randy, this takes a different route from your patch in August [1]: the
> out_tail() call stays in ManFormat.msg() and is skipped when the base
> class produced no page, so OutputFormat does not need to know about it.
> DOC blocks that are shown keep their tail, since they get their own .TH.
Yes, I had already abandoned that patch and its approach. I was (slowly)
looking at doing something like this, although probably not as succinct
as this.
Tested-by: Randy Dunlap <rdunlap@infradead.org>
Acked-by: Randy Dunlap <rdunlap@infradead.org>
Thanks.
>
> [1] https://lore.kernel.org/all/20260816054826.3988516-1-rdunlap@infradead.org/
> ---
> tools/lib/python/kdoc/kdoc_output.py | 5 +++-
> tools/unittests/test_kdoc_parser.py | 52 ++++++++++++++++++++++++++++++++++++
> 2 files changed, 56 insertions(+), 1 deletion(-)
>
> diff --git a/tools/lib/python/kdoc/kdoc_output.py b/tools/lib/python/kdoc/kdoc_output.py
> index 618b0d765ef5..659a2c6fb6be 100644
> --- a/tools/lib/python/kdoc/kdoc_output.py
> +++ b/tools/lib/python/kdoc/kdoc_output.py
> @@ -763,7 +763,10 @@ class ManFormat(OutputFormat):
> Add a tail at the end of man pages output.
> """
> super().msg(fname, name, args)
> - self.out_tail(fname, name, args)
> +
> + # Symbols dropped by the output filters produce no page
> + if self.data:
> + self.out_tail(fname, name, args)
>
> return self.data
>
> diff --git a/tools/unittests/test_kdoc_parser.py b/tools/unittests/test_kdoc_parser.py
> index c4a76ed13dbc..bcb1b1a5ccc6 100755
> --- a/tools/unittests/test_kdoc_parser.py
> +++ b/tools/unittests/test_kdoc_parser.py
> @@ -301,6 +301,58 @@ class CToMan(unittest.TestCase):
> self.assertEqual(result, expected)
>
>
> +class ManFilterTail(unittest.TestCase):
> + """
> + Symbols dropped by the output filters must not leave a man page tail.
> + """
> +
> + source = dedent("""
> + /**
> + * foo - First function
> + * @a: an argument
> + */
> + int foo(int a) { return 0; };
> +
> + /**
> + * bar - Second function
> + * @b: an argument
> + */
> + int bar(int b) { return 0; };
> + """)
> +
> + def setUp(self):
> + config = MockKdocConfig()
> + kernel_doc = KernelDoc(config, "mock.c", CTransforms())
> +
> + with patch('builtins.open', new_callable=mock_open,
> + read_data=self.source):
> + _, self.entries = kernel_doc.parse_kdoc()
> +
> + self.out_style = ManFormat()
> + self.out_style.set_config(config)
> +
> + def run_filter(self, **kwargs):
> + args = {"export": False, "internal": False, "symbol": None,
> + "nosymbol": None, "function_table": set(),
> + "enable_lineno": False, "no_doc_sections": False}
> + args.update(kwargs)
> +
> + self.out_style.set_filter(**args)
> +
> + return self.out_style.output_symbols("mock.c", self.entries)
> +
> + def test_symbol_filter(self):
> + """Only the selected symbol gets a page, with a single tail."""
> + result = self.run_filter(symbol=["foo"], function_table={"foo"})
> +
> + self.assertEqual(result.count(".TH "), 1)
> + self.assertEqual(result.count('.SH "SEE ALSO"'), 1)
> +
> + def test_all_filtered_out(self):
> + """No exported symbols: no output at all."""
> + self.assertEqual(self.run_filter(export=True), "")
> +
> +
> class CToRest(unittest.TestCase):
> out_style = RestFormat()
> config = MockKdocConfig()
>
> ---
> base-commit: 4f041d7b65b8007403cce30ecf69ad42d48ec315
> change-id: 20260929-kdoc-man-filter-eba1ff857dad
>
> Best regards,
> --
> Simon Sudarushkin <simonsudarushkin@gmail.com>
--
~Randy
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-09-30 0:29 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-29 13:36 [PATCH] docs: kdoc_output: don't add a man page tail for filtered-out symbols Simon Sudarushkin via B4 Relay
2026-09-30 0:29 ` Randy Dunlap
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®