From nobody Thu Dec 18 20:02:19 2025 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 90F9634B19A; Tue, 16 Dec 2025 14:26:24 +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=1765895184; cv=none; b=dXj9F2cZ9mYrDkbX3cajwMPFiWThoU2mgvBIGqC4+IWYnF88va532BISuEouqqniZUsRIZCI3QKLB1W1JnQSGxUA7CFX74rFTRj9inFMIBd6ydTu/lMAPId6dZJx8fXbjvIKoo3s3NuF5dy+lpIM26oWDNGzIXbHIGbOGbIkJMM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765895184; c=relaxed/simple; bh=D5Dan+chdaKCsHfpLGspv1TIRzMfinLgSlG6JG25Zz0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YsOEBZx+jgInlyvYtkD3gCzC3JtsQyuage8YjAE7TzylDX6p4yAoGoZ67cwqvBw+/u58A7UdU9u0hPqjj72Cb5YXwforM+hgXC9WienhJwTzuKQWZMvYx3MIiMshfX2cupCQhtBKm1IOIE3Ql6fS2vJPmLsmwSpSms1OQl4vIBg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=F4ZhULlt; 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="F4ZhULlt" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5BC15C4CEF1; Tue, 16 Dec 2025 14:26:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1765895184; bh=D5Dan+chdaKCsHfpLGspv1TIRzMfinLgSlG6JG25Zz0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=F4ZhULltBwmzjiMZjPBrfdObM140oLI9BuiA0GVHSyMKW4rNqKuto+4t5EgZqHQoD JtgeQLbTAUEMmOJ2HPv7YT1xCjNgyucjLBWSoyxPomvphMRp/H/uCZoeP8pMRGp4bW NzIJCAEa6kncocXw2jVxSvvl264NiOOgDKIJIBp3MorCUieREzX9JRJq/3qPYl4RMZ 70jJbUtdURE2Xd0Co8ZEgXUWFR3JkH3S3SEfnXu8r+cg0CEY5duTa+H4Pwh6Hicx4C lU11i9CWU/2FUgLgIVnle6q2tf5lyK8TMH7NsFShPSPFU+zKrGMK22r/lHaH7CqCuO fAy4M52DihLqA== Received: from mchehab by mail.kernel.org with local (Exim 4.99) (envelope-from ) id 1vVW0M-00000000ssF-2YcS; Tue, 16 Dec 2025 15:26:22 +0100 From: Mauro Carvalho Chehab To: Linux Doc Mailing List , Jonathan Corbet Cc: Mauro Carvalho Chehab , "Randy Dunlap" , linux-kernel@vger.kernel.org Subject: [PATCH v7 1/6] kernel-doc: add support for handling global variables Date: Tue, 16 Dec 2025 15:26:12 +0100 Message-ID: X-Mailer: git-send-email 2.52.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-Transfer-Encoding: quoted-printable Sender: Mauro Carvalho Chehab Content-Type: text/plain; charset="utf-8" Specially on kAPI, sometimes it is desirable to be able to describe global variables that are part of kAPI. Documenting vars with Sphinx is simple, as we don't need to parse a data struct. All we need is the variable declaration and use native C domain ::c:var: to format it for us. Add support for it. Link: https://lore.kernel.org/linux-doc/491c3022-cef8-4860-a945-c9c4a3b63c0= 9@infradead.org/T/#m947c25d95cb1d96a394410ab1131dc8e9e5013f1 Suggested-by: Randy Dunlap Tested-by: Randy Dunlap Acked-by: Randy Dunlap Signed-off-by: Mauro Carvalho Chehab --- tools/lib/python/kdoc/kdoc_output.py | 47 +++++++++++++++++++++++ tools/lib/python/kdoc/kdoc_parser.py | 56 +++++++++++++++++++++++++++- 2 files changed, 102 insertions(+), 1 deletion(-) diff --git a/tools/lib/python/kdoc/kdoc_output.py b/tools/lib/python/kdoc/k= doc_output.py index b1aaa7fc3604..50aedbb3d6de 100644 --- a/tools/lib/python/kdoc/kdoc_output.py +++ b/tools/lib/python/kdoc/kdoc_output.py @@ -199,6 +199,10 @@ class OutputFormat: self.out_enum(fname, name, args) return self.data =20 + if dtype =3D=3D "var": + self.out_var(fname, name, args) + return self.data + if dtype =3D=3D "typedef": self.out_typedef(fname, name, args) return self.data @@ -227,6 +231,9 @@ class OutputFormat: def out_enum(self, fname, name, args): """Outputs an enum""" =20 + def out_var(self, fname, name, args): + """Outputs a variable""" + def out_typedef(self, fname, name, args): """Outputs a typedef""" =20 @@ -472,6 +479,25 @@ class RestFormat(OutputFormat): self.lineprefix =3D oldprefix self.out_section(args) =20 + def out_var(self, fname, name, args): + oldprefix =3D self.lineprefix + ln =3D args.declaration_start_line + full_proto =3D args.other_stuff["full_proto"] + + self.lineprefix =3D " " + + self.data +=3D f"\n\n.. c:macro:: {name}\n\n{self.lineprefix}{full= _proto}\n\n" + + self.print_lineno(ln) + self.output_highlight(args.get('purpose', '')) + self.data +=3D "\n" + + if args.other_stuff["default_val"]: + self.data +=3D f'{self.lineprefix}**Initialization**\n\n' + self.output_highlight(f'default: ``{args.other_stuff["default_= val"]}``') + + self.out_section(args) + def out_typedef(self, fname, name, args): =20 oldprefix =3D self.lineprefix @@ -773,6 +799,27 @@ class ManFormat(OutputFormat): self.data +=3D f'.SH "{section}"' + "\n" self.output_highlight(text) =20 + def out_var(self, fname, name, args): + out_name =3D self.arg_name(args, name) + prototype =3D args.other_stuff["var_type"] + full_proto =3D args.other_stuff["full_proto"] + + self.data +=3D f'.TH "{self.modulename}" 9 "{out_name}" "{self.man= _date}" "API Manual" LINUX' + "\n" + + self.data +=3D ".SH NAME\n" + self.data +=3D f"{prototype} \\- {args['purpose']}\n" + + self.data +=3D ".SH SYNOPSIS\n" + self.data +=3D f"{full_proto}\n" + + if args.other_stuff["default_val"]: + self.data +=3D f'.SH "Initialization"' + "\n" + self.output_highlight(f'default: {args.other_stuff["default_va= l"]}') + + for section, text in args.sections.items(): + self.data +=3D f'.SH "{section}"' + "\n" + self.output_highlight(text) + def out_typedef(self, fname, name, args): module =3D self.modulename purpose =3D args.get('purpose') diff --git a/tools/lib/python/kdoc/kdoc_parser.py b/tools/lib/python/kdoc/k= doc_parser.py index 500aafc50032..06bed1a12a45 100644 --- a/tools/lib/python/kdoc/kdoc_parser.py +++ b/tools/lib/python/kdoc/kdoc_parser.py @@ -64,7 +64,7 @@ type_param =3D KernRe(r"@(\w*((\.\w+)|(->\w+))*(\.\.\.)?)= ", cache=3DFalse) # Tests for the beginning of a kerneldoc block in its various forms. # doc_block =3D doc_com + KernRe(r'DOC:\s*(.*)?', cache=3DFalse) -doc_begin_data =3D KernRe(r"^\s*\*?\s*(struct|union|enum|typedef)\b\s*(\w*= )", cache =3D False) +doc_begin_data =3D KernRe(r"^\s*\*?\s*(struct|union|enum|typedef|var)\b\s*= (\w*)", cache =3D False) doc_begin_func =3D KernRe(str(doc_com) + # initial " * ' r"(?:\w+\s*\*\s*)?" + # type (not captured) r'(?:define\s+)?' + # possible "define" (not cap= tured) @@ -927,6 +927,58 @@ class KernelDoc: self.output_declaration('enum', declaration_name, purpose=3Dself.entry.declaration_purpose) =20 + def dump_var(self, ln, proto): + """ + Store variables that are part of kAPI. + """ + VAR_ATTRIBS =3D [ + "extern", + ] + OPTIONAL_VAR_ATTR =3D "^(?:" + "|".join(VAR_ATTRIBS) + ")?" + + sub_prefixes =3D [ + (KernRe(r"__read_mostly"), ""), + (KernRe(r"__ro_after_init"), ""), + (KernRe(r"(?://.*)$"), ""), + (KernRe(r"(?:/\*.*\*/)"), ""), + (KernRe(r";$"), ""), + (KernRe(r"=3D.*"), ""), + ] + + # + # Store the full prototype before modifying it + # + full_proto =3D proto + + # + # Drop comments and macros to have a pure C prototype + # + for search, sub in sub_prefixes: + proto =3D search.sub(sub, proto) + + proto =3D proto.rstrip() + + # + # Variable name is at the end of the declaration + # + + r=3D KernRe(OPTIONAL_VAR_ATTR + r"\w.*\s+(?:\*+)?([\w_]+)\s*[\d\]\= []*\s*(=3D.*)?") + if not r.match(proto): + self.emit_msg(ln,f"{proto}: can't parse variable") + return + + var_type =3D r.group(0) + declaration_name =3D r.group(1) + default_val =3D r.group(2) + if default_val: + default_val =3D default_val.lstrip("=3D").strip() + + self.output_declaration("var", declaration_name, + full_proto=3Dfull_proto, + var_type=3Dvar_type, + default_val=3Ddefault_val, + purpose=3Dself.entry.declaration_purpose) + def dump_declaration(self, ln, prototype): """ Stores a data declaration inside self.entries array. @@ -938,6 +990,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 =3D=3D "var": + self.dump_var(ln, prototype) else: # This would be a bug self.emit_message(ln, f'Unknown declaration type: {self.entry.= decl_type}') --=20 2.52.0