summaryrefslogtreecommitdiff
path: root/tools/lib/python/kdoc/kdoc_parser.py
diff options
context:
space:
mode:
authorJonathan Corbet <corbet@lwn.net>2025-12-23 00:52:57 +0300
committerJonathan Corbet <corbet@lwn.net>2025-12-23 00:52:57 +0300
commitd07e0857dcb647792a939a769fc73c20de20c28a (patch)
tree95566c9ceee76d92fd46a5d73ebbbbe6ac96df55 /tools/lib/python/kdoc/kdoc_parser.py
parent82e87387f6e2af9f69a7528733e953fd22e815aa (diff)
parentaaacd70fb77afe75075e8bdf8e493b0af42eeabd (diff)
downloadlinux-d07e0857dcb647792a939a769fc73c20de20c28a.tar.xz
Merge branch 'mauro-vars' into docs-mw
Mauro says: As suggested and discussed with Randy, this small series add support for documenting variables using kernel-doc. - patch 1: add support for the new feature; - patch 2: extends to support DEFINE_*; - patch 3: document two media vars; - patch 4: fix an issue on kernel-doc.rst markups and automarkup; - patch 5: document it; - patch 6: better handle DEFINE_ macros when they don't have static/type; Since version 5, I'm using "c:macro" to describe variables, as it avoids Sphinx C domain to try parse the variable. This makes it more flexible and easier to maintain in long term.
Diffstat (limited to 'tools/lib/python/kdoc/kdoc_parser.py')
-rw-r--r--tools/lib/python/kdoc/kdoc_parser.py79
1 files changed, 78 insertions, 1 deletions
diff --git a/tools/lib/python/kdoc/kdoc_parser.py b/tools/lib/python/kdoc/kdoc_parser.py
index 500aafc50032..e137bd9a7dac 100644
--- a/tools/lib/python/kdoc/kdoc_parser.py
+++ b/tools/lib/python/kdoc/kdoc_parser.py
@@ -64,7 +64,7 @@ type_param = KernRe(r"@(\w*((\.\w+)|(->\w+))*(\.\.\.)?)", cache=False)
# Tests for the beginning of a kerneldoc block in its various forms.
#
doc_block = doc_com + KernRe(r'DOC:\s*(.*)?', cache=False)
-doc_begin_data = KernRe(r"^\s*\*?\s*(struct|union|enum|typedef)\b\s*(\w*)", cache = False)
+doc_begin_data = KernRe(r"^\s*\*?\s*(struct|union|enum|typedef|var)\b\s*(\w*)", cache = False)
doc_begin_func = KernRe(str(doc_com) + # initial " * '
r"(?:\w+\s*\*\s*)?" + # type (not captured)
r'(?:define\s+)?' + # possible "define" (not captured)
@@ -927,6 +927,81 @@ class KernelDoc:
self.output_declaration('enum', declaration_name,
purpose=self.entry.declaration_purpose)
+ def dump_var(self, ln, proto):
+ """
+ Store variables that are part of kAPI.
+ """
+ VAR_ATTRIBS = [
+ "extern",
+ ]
+ OPTIONAL_VAR_ATTR = "^(?:" + "|".join(VAR_ATTRIBS) + ")?"
+
+ sub_prefixes = [
+ (KernRe(r"__read_mostly"), ""),
+ (KernRe(r"__ro_after_init"), ""),
+ (KernRe(r"(?://.*)$"), ""),
+ (KernRe(r"(?:/\*.*\*/)"), ""),
+ (KernRe(r";$"), ""),
+ (KernRe(r"=.*"), ""),
+ ]
+
+ #
+ # Store the full prototype before modifying it
+ #
+ full_proto = proto
+ declaration_name = None
+
+ #
+ # Handle macro definitions
+ #
+ macro_prefixes = [
+ KernRe(r"DEFINE_[\w_]+\s*\(([\w_]+)\)"),
+ ]
+
+ for r in macro_prefixes:
+ match = r.search(proto)
+ if match:
+ declaration_name = match.group(1)
+ break
+
+ #
+ # Drop comments and macros to have a pure C prototype
+ #
+ if not declaration_name:
+ for r, sub in sub_prefixes:
+ proto = r.sub(sub, proto)
+
+ proto = proto.rstrip()
+
+ #
+ # Variable name is at the end of the declaration
+ #
+
+ default_val = None
+
+ r= KernRe(OPTIONAL_VAR_ATTR + r"\w.*\s+(?:\*+)?([\w_]+)\s*[\d\]\[]*\s*(=.*)?")
+ if r.match(proto):
+ if not declaration_name:
+ declaration_name = r.group(1)
+
+ default_val = r.group(2)
+ else:
+ r= KernRe(OPTIONAL_VAR_ATTR + r"(?:\w.*)?\s+(?:\*+)?(?:[\w_]+)\s*[\d\]\[]*\s*(=.*)?")
+ if r.match(proto):
+ default_val = r.group(1)
+
+ if not declaration_name:
+ self.emit_msg(ln,f"{proto}: can't parse variable")
+ return
+
+ if default_val:
+ default_val = default_val.lstrip("=").strip()
+
+ self.output_declaration("var", declaration_name,
+ full_proto=full_proto,
+ default_val=default_val,
+ purpose=self.entry.declaration_purpose)
+
def dump_declaration(self, ln, prototype):
"""
Stores a data declaration inside self.entries array.
@@ -938,6 +1013,8 @@ class KernelDoc:
self.dump_typedef(ln, prototype)
elif self.entry.decl_type in ["union", "struct"]:
self.dump_struct(ln, prototype)
+ elif self.entry.decl_type == "var":
+ self.dump_var(ln, prototype)
else:
# This would be a bug
self.emit_message(ln, f'Unknown declaration type: {self.entry.decl_type}')