Em Tue, 9 Sep 2025 00:27:20 -0700 Randy Dunlap <rdunlap@xxxxxxxxxxxxx> escreveu: > Hi Mauro, > > I have a few patch nits below, then some testing info. > > > On 9/7/25 9:22 AM, Mauro Carvalho Chehab wrote: > > 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 natice C domain ::c:var: to format it > > for us. > > > > Add support for it. > > > > Link: https://lore.kernel.org/linux-doc/491c3022-cef8-4860-a945-c9c4a3b63c09@xxxxxxxxxxxxx/T/#m947c25d95cb1d96a394410ab1131dc8e9e5013f1 > > Suggested-by: Randy Dunlap <rdunlap@xxxxxxxxxxxxx> > > Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@xxxxxxxxxx> > > --- > > scripts/lib/kdoc/kdoc_output.py | 31 +++++++++++++++++++++++++++++++ > > scripts/lib/kdoc/kdoc_parser.py | 25 ++++++++++++++++++++++++- > > 2 files changed, 55 insertions(+), 1 deletion(-) > > > > diff --git a/scripts/lib/kdoc/kdoc_output.py b/scripts/lib/kdoc/kdoc_output.py > > index 1eca9a918558..405a5c407522 100644 > > --- a/scripts/lib/kdoc/kdoc_output.py > > +++ b/scripts/lib/kdoc/kdoc_output.py > > @@ -199,6 +199,10 @@ class OutputFormat: > > self.out_enum(fname, name, args) > > return self.data > > > > + if dtype == "global": > > + self.out_global(fname, name, args) > > + return self.data > > + > > if dtype == "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""" > > > > + def out_global(self, fname, name, args): > > + """Outputs a global variable""" > > + > > def out_typedef(self, fname, name, args): > > """Outputs a typedef""" > > > > @@ -472,6 +479,18 @@ class RestFormat(OutputFormat): > > self.lineprefix = oldprefix > > self.out_section(args) > > > > + def out_global(self, fname, name, args): > > + oldprefix = self.lineprefix > > + ln = args.declaration_start_line > > + prototype = args.other_stuff["var_type"] > > + > > + self.data += f" > > > > .. c:var:: {prototype} > > > > " > > Are the 5 lines above supposed to be on one line? Did git send-email split that up for you? > There are a few others like this below. > patch(1) complains when I try to apply the patch from this email. Weird. I'm testing a new mailbomb script... perhaps it is causing those issues. Yeah, the code snippet is: + def out_global(self, fname, name, args): + oldprefix = self.lineprefix + ln = args.declaration_start_line + prototype = args.other_stuff["var_type"] + + self.data += f"\n\n.. c:var:: {prototype}\n\n" + + self.print_lineno(ln) + self.lineprefix = " " + self.output_highlight(args.get('purpose', '')) + self.data += "\n" It sounds the mailbomb script replaced "\n" with a new line :-( > > + self.print_lineno(ln) > > + self.lineprefix = " " > > + self.output_highlight(args.get('purpose', '')) > > + self.data += " > > " > > + > > def out_typedef(self, fname, name, args): > > > > oldprefix = self.lineprefix > > @@ -772,6 +791,18 @@ class ManFormat(OutputFormat): > > self.data += f'.SH "{section}"' + " > > " > > self.output_highlight(text) > > > > + def out_global(self, fname, name, args): > > + out_name = self.arg_name(args, name) > > + prototype = args.other_stuff["var_type"] > > + > > + self.data += f'.TH "{self.modulename}" 9 "{out_name}" "{self.man_date}" "API Manual" LINUX' + " > > " > > + > > + self.data += ".SH NAME > > " > > + self.data += f"{prototype} \- {args['purpose']} > > Python complains about the "\-" above. Other places nearby use "\\-" > so I changed it to that instead. Hope that's OK. > Yes. Again, mailbomb script mangled it. The original code is: + self.data += f"{prototype} \\- {args['purpose']}\n" I'm pasting the full patch at the end. > > " > > + > > + self.data += ".SH SYNOPSIS > > " > > + self.data += f"enum {name}" + " { > > " > > + > > def out_typedef(self, fname, name, args): > > module = self.modulename > > purpose = args.get('purpose') > > diff --git a/scripts/lib/kdoc/kdoc_parser.py b/scripts/lib/kdoc/kdoc_parser.py > > index 574972e1f741..e2a3f4574894 100644 > > --- a/scripts/lib/kdoc/kdoc_parser.py > > +++ b/scripts/lib/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)\s*(\w*)", cache = False) > > +doc_begin_data = KernRe(r"^\s*\*?\s*(struct|union|enum|typedef|global)\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) > > @@ -886,6 +886,27 @@ class KernelDoc: > > self.output_declaration('enum', declaration_name, > > purpose=self.entry.declaration_purpose) > > > > + def dump_global(self, ln, proto): > > + """ > > + Stores global variables that are part of kAPI. > > + """ > > + VAR_ATTRIBS = [ > > + "extern", > > + ] > > + OPTIONAL_VAR_ATTR = "^(?:" + "|".join(VAR_ATTRIBS) + ")?" > > + > > + r= KernRe(OPTIONAL_VAR_ATTR + r"(\w.*)\s+([\w_]+)[\d\]\[]*\s*;(?:#.*)?$") > > + if not r.match(proto): > > + self.emit_msg(ln,f"{proto}: can't parse variable") > > + return > > + > > + declaration_name = r.group(2) > > + var_type = r.group(0) > > + > > + self.output_declaration("global", declaration_name, > > + var_type=var_type, > > + purpose=self.entry.declaration_purpose) > > + > > def dump_declaration(self, ln, prototype): > > """ > > Stores a data declaration inside self.entries array. > > @@ -897,6 +918,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 == "global": > > + self.dump_global(ln, prototype) > > else: > > # This would be a bug > > self.emit_message(ln, f'Unknown declaration type: {self.entry.decl_type}') > So, I grabbed some global data from 6-8 places in the kernel and put them intoinit/kdoc-globals-test.c. Then I modified Documentation/core-api/kernel-api.rst > like this at the end of that file: > > + > +Kernel Globals > +========================== > + > +.. kernel-doc:: init/kdoc-globals-test.c > + :identifiers: > > The html output says > "Kernel Globals" > but nothing else. I usually don't add :identifiers: on kernel-doc entries. If you use identifiers, you need to explicitly tell what symbols you want. As a reference, kerneldoc.py logic for identifiers is: if 'identifiers' in self.options: identifiers = self.options.get('identifiers').split() if identifiers: for i in identifiers: i = i.rstrip("\\").strip() if not i: continue cmd += ['-function', i] self.msg_args["symbol"].append(i) without it, it will pick the entire set of symbols. > My test files are attached. I dumbed down (simplified) a few > of the globals from fancy types to just unsigned long, but that > didn't help the output results any. Looking on your attachment, you can either drop :identifiers: or list all of them: .. kernel-doc:: init/kdoc-globals-test.c :identifiers: ROOT_DEV loop_per_jiffy :identifiers: preset_lpj (here, it should only show those 3 symbols) see, having this: .. kernel-doc:: init/kdoc-globals-test.c :identifiers: ROOT_DEV will run: $ ./scripts/kernel-doc init/kdoc-globals-test.c -function ROOT_DEV .. c:var:: unsigned long ROOT_DEV; system root device > What's happening? > Thanks. Thanks, Mauro ---