summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2026-07-26 21:52:23 +0100
committerMark Brown <broonie@kernel.org>2026-07-26 21:52:23 +0100
commit60d10ed1b26334b1ef8f6c0e46f07a92599c1392 (patch)
tree3c950c35187aef61b6884a4fdf4355975f790139 /tools
parentfb45da6fb1c023e2739759f8b2035f120f3f2504 (diff)
parentd699a5da103942fdc0a8a5383359bdec01fc19dd (diff)
downloadlinux-next-60d10ed1b26334b1ef8f6c0e46f07a92599c1392.tar.gz
linux-next-60d10ed1b26334b1ef8f6c0e46f07a92599c1392.zip
Merge branch 'docs-next' of git://git.lwn.net/linux.git
Diffstat (limited to 'tools')
-rw-r--r--tools/lib/python/kdoc/kdoc_output.py2
-rw-r--r--tools/lib/python/kdoc/kdoc_parser.py51
2 files changed, 50 insertions, 3 deletions
diff --git a/tools/lib/python/kdoc/kdoc_output.py b/tools/lib/python/kdoc/kdoc_output.py
index de107ab4a281..618b0d765ef5 100644
--- a/tools/lib/python/kdoc/kdoc_output.py
+++ b/tools/lib/python/kdoc/kdoc_output.py
@@ -624,7 +624,7 @@ class ManFormat(OutputFormat):
``manual``
Defaults to ``Kernel API Manual``.
- The above controls the output of teh corresponding fields on troff
+ The above controls the output of the corresponding fields on troff
title headers, which will be filled like this::
.TH "{name}" {section} "{date}" "{modulename}" "{manual}"
diff --git a/tools/lib/python/kdoc/kdoc_parser.py b/tools/lib/python/kdoc/kdoc_parser.py
index 2dedda215c22..884f42584667 100644
--- a/tools/lib/python/kdoc/kdoc_parser.py
+++ b/tools/lib/python/kdoc/kdoc_parser.py
@@ -11,6 +11,7 @@ and extract embedded documentation comments from it.
import sys
import re
+import difflib
from pprint import pformat
from kdoc.c_lex import CTokenizer, tokenizer_set_log
@@ -558,6 +559,50 @@ class KernelDoc:
self.push_parameter(ln, decl_type, param, dtype,
arg, declaration_name)
+ def get_suggestions_hint(self, decl_name, possible_names):
+ # For decl name 'flags' or 'flgas', suggests 'substruct.flags'
+ submember_exact = []
+ submember_substrings = []
+ submember_suggestions = []
+ for possible_name in possible_names:
+ parts = possible_name.strip().split('.')
+ if len(parts) < 2:
+ continue
+
+ final_part = parts[-1]
+ if decl_name == final_part:
+ submember_exact.append(possible_name)
+ elif decl_name in final_part:
+ submember_substrings.append(possible_name)
+ elif difflib.get_close_matches(decl_name, [final_part]):
+ submember_suggestions.append(possible_name)
+
+ # For decl name 'flgas', suggests 'flags'
+ full_suggestions = difflib.get_close_matches(decl_name, possible_names)
+
+ # For decl name 'member', suggests 'longer_member'
+ full_substrings = [name for name in possible_names if decl_name in name]
+
+ ordered_lists = [
+ submember_exact,
+ submember_substrings,
+ submember_suggestions,
+ full_suggestions,
+ full_substrings,
+ ]
+
+ # Deduplicate but maintain order from most to least likely:
+ unique_suggestions = {}
+ for suggestion_list in ordered_lists:
+ for suggestion in suggestion_list:
+ unique_suggestions[suggestion] = None
+
+ suggestions = list(unique_suggestions.keys())
+ if not suggestions:
+ return ""
+
+ return f"(did you mean one of: '{"', '".join(suggestions)}')"
+
def check_sections(self, ln, decl_name, decl_type):
"""
Check for errors inside sections, emitting warnings if not found
@@ -566,12 +611,13 @@ class KernelDoc:
for section in self.entry.sections:
if section not in self.entry.parameterlist and \
not known_sections.search(section):
+ hint = self.get_suggestions_hint(section, self.entry.parameterlist)
if decl_type == 'function':
dname = f"{decl_type} parameter"
else:
dname = f"{decl_type} member"
self.emit_msg(ln,
- f"Excess {dname} '{section}' description in '{decl_name}'")
+ f"Excess {dname} '{section}' description in '{decl_name}' {hint}".strip())
#
# Check that documented parameter names (from doc comments, including
@@ -591,12 +637,13 @@ class KernelDoc:
if param_name in self.entry.parameterlist:
continue
+ hint = self.get_suggestions_hint(param_name, self.entry.parameterlist)
if decl_type == 'function':
dname = f"{decl_type} parameter"
else:
dname = f"{decl_type} member"
self.emit_msg(ln,
- f"Excess {dname} '{param_name}' description in '{decl_name}'")
+ f"Excess {dname} '{param_name}' description in '{decl_name}' {hint}".strip())
def check_return_section(self, ln, declaration_name, return_type):
"""