From 45005b27c191826dd88622c1e35a9448d861af3b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 8 Dec 2017 09:05:12 -0500 Subject: kernel-doc: parse DECLARE_KFIFO and DECLARE_KFIFO_PTR() On media, we now have an struct declared with: struct lirc_fh { struct list_head list; struct rc_dev *rc; int carrier_low; bool send_timeout_reports; DECLARE_KFIFO_PTR(rawir, unsigned int); DECLARE_KFIFO_PTR(scancodes, struct lirc_scancode); wait_queue_head_t wait_poll; u8 send_mode; u8 rec_mode; }; gpiolib.c has a similar declaration with DECLARE_KFIFO(). Currently, those produce the following error: ./include/media/rc-core.h:96: warning: No description found for parameter 'int' ./include/media/rc-core.h:96: warning: No description found for parameter 'lirc_scancode' ./include/media/rc-core.h:96: warning: Excess struct member 'rawir' description in 'lirc_fh' ./include/media/rc-core.h:96: warning: Excess struct member 'scancodes' description in 'lirc_fh' ../drivers/gpio/gpiolib.c:601: warning: No description found for parameter '16' ../drivers/gpio/gpiolib.c:601: warning: Excess struct member 'events' description in 'lineevent_state' So, teach kernel-doc how to parse DECLARE_KFIFO() and DECLARE_KFIFO_PTR(). While here, relax at the past DECLARE_foo() macros, accepting a random number of spaces after comma. The addition of DECLARE_KFIFO() was Suggested-by: Randy Dunlap Signed-off-by: Mauro Carvalho Chehab Tested-by: Randy Dunlap Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index df0f045a9a89..675c525ec5b9 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -2208,9 +2208,13 @@ sub dump_struct($$) { $members =~ s/__aligned\s*\([^;]*\)//gos; $members =~ s/\s*CRYPTO_MINALIGN_ATTR//gos; # replace DECLARE_BITMAP - $members =~ s/DECLARE_BITMAP\s*\(([^,)]+), ([^,)]+)\)/unsigned long $1\[BITS_TO_LONGS($2)\]/gos; + $members =~ s/DECLARE_BITMAP\s*\(([^,)]+),\s*([^,)]+)\)/unsigned long $1\[BITS_TO_LONGS($2)\]/gos; # replace DECLARE_HASHTABLE - $members =~ s/DECLARE_HASHTABLE\s*\(([^,)]+), ([^,)]+)\)/unsigned long $1\[1 << (($2) - 1)\]/gos; + $members =~ s/DECLARE_HASHTABLE\s*\(([^,)]+),\s*([^,)]+)\)/unsigned long $1\[1 << (($2) - 1)\]/gos; + # replace DECLARE_KFIFO + $members =~ s/DECLARE_KFIFO\s*\(([^,)]+),\s*([^,)]+),\s*([^,)]+)\)/$2 \*$1/gos; + # replace DECLARE_KFIFO_PTR + $members =~ s/DECLARE_KFIFO_PTR\s*\(([^,)]+),\s*([^,)]+)\)/$2 \*$1/gos; create_parameterlist($members, ';', $file); check_sections($file, $declaration_name, $decl_type, $sectcheck, $struct_actual, $nested); -- cgit v1.2.3-59-g8ed1b From 857af3b775940865c215ab168212ebc96ab80f57 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 18 Dec 2017 10:30:08 -0200 Subject: docs: get rid of kernel-doc-nano-HOWTO.txt Everything there is already described at Documentation/doc-guide/kernel-doc.rst. So, there's no reason why to keep it anymore. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Jonathan Corbet --- Documentation/00-INDEX | 2 - Documentation/kernel-doc-nano-HOWTO.txt | 322 -------------------------------- scripts/kernel-doc | 2 +- 3 files changed, 1 insertion(+), 325 deletions(-) delete mode 100644 Documentation/kernel-doc-nano-HOWTO.txt (limited to 'scripts') diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX index 7023bfaec21c..7f3a0728ccf2 100644 --- a/Documentation/00-INDEX +++ b/Documentation/00-INDEX @@ -228,8 +228,6 @@ isdn/ - directory with info on the Linux ISDN support, and supported cards. kbuild/ - directory with info about the kernel build process. -kernel-doc-nano-HOWTO.txt - - outdated info about kernel-doc documentation. kdump/ - directory with mini HowTo on getting the crash dump code to work. doc-guide/ diff --git a/Documentation/kernel-doc-nano-HOWTO.txt b/Documentation/kernel-doc-nano-HOWTO.txt deleted file mode 100644 index c23e2c5ab80d..000000000000 --- a/Documentation/kernel-doc-nano-HOWTO.txt +++ /dev/null @@ -1,322 +0,0 @@ -NOTE: this document is outdated and will eventually be removed. See -Documentation/doc-guide/ for current information. - -kernel-doc nano-HOWTO -===================== - -How to format kernel-doc comments ---------------------------------- - -In order to provide embedded, 'C' friendly, easy to maintain, -but consistent and extractable documentation of the functions and -data structures in the Linux kernel, the Linux kernel has adopted -a consistent style for documenting functions and their parameters, -and structures and their members. - -The format for this documentation is called the kernel-doc format. -It is documented in this Documentation/kernel-doc-nano-HOWTO.txt file. - -This style embeds the documentation within the source files, using -a few simple conventions. The scripts/kernel-doc perl script, the -Documentation/sphinx/kerneldoc.py Sphinx extension and other tools understand -these conventions, and are used to extract this embedded documentation -into various documents. - -In order to provide good documentation of kernel functions and data -structures, please use the following conventions to format your -kernel-doc comments in Linux kernel source. - -We definitely need kernel-doc formatted documentation for functions -that are exported to loadable modules using EXPORT_SYMBOL. - -We also look to provide kernel-doc formatted documentation for -functions externally visible to other kernel files (not marked -"static"). - -We also recommend providing kernel-doc formatted documentation -for private (file "static") routines, for consistency of kernel -source code layout. But this is lower priority and at the -discretion of the MAINTAINER of that kernel source file. - -Data structures visible in kernel include files should also be -documented using kernel-doc formatted comments. - -The opening comment mark "/**" is reserved for kernel-doc comments. -Only comments so marked will be considered by the kernel-doc scripts, -and any comment so marked must be in kernel-doc format. Do not use -"/**" to be begin a comment block unless the comment block contains -kernel-doc formatted comments. The closing comment marker for -kernel-doc comments can be either "*/" or "**/", but "*/" is -preferred in the Linux kernel tree. - -Kernel-doc comments should be placed just before the function -or data structure being described. - -Example kernel-doc function comment: - -/** - * foobar() - short function description of foobar - * @arg1: Describe the first argument to foobar. - * @arg2: Describe the second argument to foobar. - * One can provide multiple line descriptions - * for arguments. - * - * A longer description, with more discussion of the function foobar() - * that might be useful to those using or modifying it. Begins with - * empty comment line, and may include additional embedded empty - * comment lines. - * - * The longer description can have multiple paragraphs. - * - * Return: Describe the return value of foobar. - */ - -The short description following the subject can span multiple lines -and ends with an @argument description, an empty line or the end of -the comment block. - -The @argument descriptions must begin on the very next line following -this opening short function description line, with no intervening -empty comment lines. - -If a function parameter is "..." (varargs), it should be listed in -kernel-doc notation as: - * @...: description - -The return value, if any, should be described in a dedicated section -named "Return". - -Example kernel-doc data structure comment. - -/** - * struct blah - the basic blah structure - * @mem1: describe the first member of struct blah - * @mem2: describe the second member of struct blah, - * perhaps with more lines and words. - * - * Longer description of this structure. - */ - -The kernel-doc function comments describe each parameter to the -function, in order, with the @name lines. - -The kernel-doc data structure comments describe each structure member -in the data structure, with the @name lines. - -The longer description formatting is "reflowed", losing your line -breaks. So presenting carefully formatted lists within these -descriptions won't work so well; derived documentation will lose -the formatting. - -See the section below "How to add extractable documentation to your -source files" for more details and notes on how to format kernel-doc -comments. - -Components of the kernel-doc system ------------------------------------ - -Many places in the source tree have extractable documentation in the -form of block comments above functions. The components of this system -are: - -- scripts/kernel-doc - - This is a perl script that hunts for the block comments and can mark - them up directly into DocBook, ReST, man, text, and HTML. (No, not - texinfo.) - -- scripts/docproc.c - - This is a program for converting SGML template files into SGML - files. When a file is referenced it is searched for symbols - exported (EXPORT_SYMBOL), to be able to distinguish between internal - and external functions. - It invokes kernel-doc, giving it the list of functions that - are to be documented. - Additionally it is used to scan the SGML template files to locate - all the files referenced herein. This is used to generate dependency - information as used by make. - -- Makefile - - The targets 'xmldocs', 'latexdocs', 'pdfdocs', 'epubdocs'and 'htmldocs' - are used to build XML DocBook files, LaTeX files, PDF files, - ePub files and html files in Documentation/. - -How to extract the documentation --------------------------------- - -If you just want to read the ready-made books on the various -subsystems, just type 'make epubdocs', or 'make pdfdocs', or 'make htmldocs', -depending on your preference. If you would rather read a different format, -you can type 'make xmldocs' and then use DocBook tools to convert -Documentation/output/*.xml to a format of your choice (for example, -'db2html ...' if 'make htmldocs' was not defined). - -If you want to see man pages instead, you can do this: - -$ cd linux -$ scripts/kernel-doc -man $(find -name '*.c') | split-man.pl /tmp/man -$ scripts/kernel-doc -man $(find -name '*.h') | split-man.pl /tmp/man - -Here is split-man.pl: - ---> -#!/usr/bin/perl - -if ($#ARGV < 0) { - die "where do I put the results?\n"; -} - -mkdir $ARGV[0],0777; -$state = 0; -while () { - if (/^\.TH \"[^\"]*\" 9 \"([^\"]*)\"/) { - if ($state == 1) { close OUT } - $state = 1; - $fn = "$ARGV[0]/$1.9"; - print STDERR "Creating $fn\n"; - open OUT, ">$fn" or die "can't open $fn: $!\n"; - print OUT $_; - } elsif ($state != 0) { - print OUT $_; - } -} - -close OUT; -<-- - -If you just want to view the documentation for one function in one -file, you can do this: - -$ scripts/kernel-doc -man -function fn file | nroff -man | less - -or this: - -$ scripts/kernel-doc -text -function fn file - - -How to add extractable documentation to your source files ---------------------------------------------------------- - -The format of the block comment is like this: - -/** - * function_name(:)? (- short description)? -(* @parameterx(space)*: (description of parameter x)?)* -(* a blank line)? - * (Description:)? (Description of function)? - * (section header: (section description)? )* -(*)?*/ - -All "description" text can span multiple lines, although the -function_name & its short description are traditionally on a single line. -Description text may also contain blank lines (i.e., lines that contain -only a "*"). - -"section header:" names must be unique per function (or struct, -union, typedef, enum). - -Use the section header "Return" for sections describing the return value -of a function. - -Avoid putting a spurious blank line after the function name, or else the -description will be repeated! - -All descriptive text is further processed, scanning for the following special -patterns, which are highlighted appropriately. - -'funcname()' - function -'$ENVVAR' - environment variable -'&struct_name' - name of a structure (up to two words including 'struct') -'@parameter' - name of a parameter -'%CONST' - name of a constant. - -NOTE 1: The multi-line descriptive text you provide does *not* recognize -line breaks, so if you try to format some text nicely, as in: - - Return: - 0 - cool - 1 - invalid arg - 2 - out of memory - -this will all run together and produce: - - Return: 0 - cool 1 - invalid arg 2 - out of memory - -NOTE 2: If the descriptive text you provide has lines that begin with -some phrase followed by a colon, each of those phrases will be taken as -a new section heading, which means you should similarly try to avoid text -like: - - Return: - 0: cool - 1: invalid arg - 2: out of memory - -every line of which would start a new section. Again, probably not -what you were after. - -Take a look around the source tree for examples. - - -kernel-doc for structs, unions, enums, and typedefs ---------------------------------------------------- - -Beside functions you can also write documentation for structs, unions, -enums and typedefs. Instead of the function name you must write the name -of the declaration; the struct/union/enum/typedef must always precede -the name. Nesting of declarations is not supported. -Use the argument mechanism to document members or constants. - -Inside a struct description, you can use the "private:" and "public:" -comment tags. Structure fields that are inside a "private:" area -are not listed in the generated output documentation. The "private:" -and "public:" tags must begin immediately following a "/*" comment -marker. They may optionally include comments between the ":" and the -ending "*/" marker. - -Example: - -/** - * struct my_struct - short description - * @a: first member - * @b: second member - * - * Longer description - */ -struct my_struct { - int a; - int b; -/* private: internal use only */ - int c; -}; - - -Including documentation blocks in source files ----------------------------------------------- - -To facilitate having source code and comments close together, you can -include kernel-doc documentation blocks that are free-form comments -instead of being kernel-doc for functions, structures, unions, -enums, or typedefs. This could be used for something like a -theory of operation for a driver or library code, for example. - -This is done by using a DOC: section keyword with a section title. E.g.: - -/** - * DOC: Theory of Operation - * - * The whizbang foobar is a dilly of a gizmo. It can do whatever you - * want it to do, at any time. It reads your mind. Here's how it works. - * - * foo bar splat - * - * The only drawback to this gizmo is that is can sometimes damage - * hardware, software, or its subject(s). - */ - -DOC: sections are used in ReST files. - -Tim. -*/ diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 675c525ec5b9..bed74e9bc141 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -48,7 +48,7 @@ Read C language source or header FILEs, extract embedded documentation comments, and print formatted documentation to standard output. The documentation comments are identified by "/**" opening comment mark. See -Documentation/kernel-doc-nano-HOWTO.txt for the documentation comment syntax. +Documentation/doc-guide/kernel-doc.rst for the documentation comment syntax. Output format selection (mutually exclusive): -docbook Output DocBook format. -- cgit v1.2.3-59-g8ed1b From b05142675310d2ac80276569e151742f880e3ec3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 18 Dec 2017 10:30:09 -0200 Subject: scripts: kernel-doc: get rid of unused output formats Since there isn't any docbook code anymore upstream, we can get rid of several output formats: - docbook/xml, html, html5 and list formats were used by the old build system; - As ReST is text, there's not much sense on outputting on a different text format. After this patch, only man and rst output formats are supported. Signed-off-by: Mauro Carvalho Chehab Acked-by: Jani Nikula Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 1183 +--------------------------------------------------- 1 file changed, 4 insertions(+), 1179 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index bed74e9bc141..c8ad05eb3e5e 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -51,13 +51,8 @@ The documentation comments are identified by "/**" opening comment mark. See Documentation/doc-guide/kernel-doc.rst for the documentation comment syntax. Output format selection (mutually exclusive): - -docbook Output DocBook format. - -html Output HTML format. - -html5 Output HTML5 format. - -list Output symbol list format. This is for use by docproc. -man Output troff manual page format. This is the default. -rst Output reStructuredText format. - -text Output plain text format. -none Do not output documentation, only warnings. Output selection (mutually exclusive): @@ -225,84 +220,11 @@ my $type_typedef = '\&(typedef\s*([_\w]+))'; my $type_union = '\&(union\s*([_\w]+))'; my $type_member = '\&([_\w]+)(\.|->)([_\w]+)'; my $type_fallback = '\&([_\w]+)'; -my $type_enum_xml = '\&(enum\s*([_\w]+))'; -my $type_struct_xml = '\&(struct\s*([_\w]+))'; -my $type_typedef_xml = '\&(typedef\s*([_\w]+))'; -my $type_union_xml = '\&(union\s*([_\w]+))'; -my $type_member_xml = '\&([_\w]+)(\.|-\>)([_\w]+)'; -my $type_fallback_xml = '\&([_\w]+)'; my $type_member_func = $type_member . '\(\)'; # Output conversion substitutions. # One for each output format -# these work fairly well -my @highlights_html = ( - [$type_constant, "\$1"], - [$type_constant2, "\$1"], - [$type_func, "\$1"], - [$type_enum_xml, "\$1"], - [$type_struct_xml, "\$1"], - [$type_typedef_xml, "\$1"], - [$type_union_xml, "\$1"], - [$type_env, "\$1"], - [$type_param, "\$1"], - [$type_member_xml, "\$1\$2\$3"], - [$type_fallback_xml, "\$1"] - ); -my $local_lt = "\\\\\\\\lt:"; -my $local_gt = "\\\\\\\\gt:"; -my $blankline_html = $local_lt . "p" . $local_gt; # was "

" - -# html version 5 -my @highlights_html5 = ( - [$type_constant, "\$1"], - [$type_constant2, "\$1"], - [$type_func, "\$1"], - [$type_enum_xml, "\$1"], - [$type_struct_xml, "\$1"], - [$type_typedef_xml, "\$1"], - [$type_union_xml, "\$1"], - [$type_env, "\$1"], - [$type_param, "\$1]"], - [$type_member_xml, "\$1\$2\$3"], - [$type_fallback_xml, "\$1"] - ); -my $blankline_html5 = $local_lt . "br /" . $local_gt; - -# XML, docbook format -my @highlights_xml = ( - ["([^=])\\\"([^\\\"<]+)\\\"", "\$1\$2"], - [$type_constant, "\$1"], - [$type_constant2, "\$1"], - [$type_enum_xml, "\$1"], - [$type_struct_xml, "\$1"], - [$type_typedef_xml, "\$1"], - [$type_union_xml, "\$1"], - [$type_param, "\$1"], - [$type_func, "\$1"], - [$type_env, "\$1"], - [$type_member_xml, "\$1\$2\$3"], - [$type_fallback_xml, "\$1"] - ); -my $blankline_xml = $local_lt . "/para" . $local_gt . $local_lt . "para" . $local_gt . "\n"; - -# gnome, docbook format -my @highlights_gnome = ( - [$type_constant, "\$1"], - [$type_constant2, "\$1"], - [$type_func, "\$1"], - [$type_enum, "\$1"], - [$type_struct, "\$1"], - [$type_typedef, "\$1"], - [$type_union, "\$1"], - [$type_env, "\$1"], - [$type_param, "\$1" ], - [$type_member, "\$1\$2\$3"], - [$type_fallback, "\$1"] - ); -my $blankline_gnome = "\n"; - # these are pretty rough my @highlights_man = ( [$type_constant, "\$1"], @@ -318,21 +240,6 @@ my @highlights_man = ( ); my $blankline_man = ""; -# text-mode -my @highlights_text = ( - [$type_constant, "\$1"], - [$type_constant2, "\$1"], - [$type_func, "\$1"], - [$type_enum, "\$1"], - [$type_struct, "\$1"], - [$type_typedef, "\$1"], - [$type_union, "\$1"], - [$type_param, "\$1"], - [$type_member, "\$1\$2\$3"], - [$type_fallback, "\$1"] - ); -my $blankline_text = ""; - # rst-mode my @highlights_rst = ( [$type_constant, "``\$1``"], @@ -352,21 +259,6 @@ my @highlights_rst = ( ); my $blankline_rst = "\n"; -# list mode -my @highlights_list = ( - [$type_constant, "\$1"], - [$type_constant2, "\$1"], - [$type_func, "\$1"], - [$type_enum, "\$1"], - [$type_struct, "\$1"], - [$type_typedef, "\$1"], - [$type_union, "\$1"], - [$type_param, "\$1"], - [$type_member, "\$1"], - [$type_fallback, "\$1"] - ); -my $blankline_list = ""; - # read arguments if ($#ARGV == -1) { usage(); @@ -501,38 +393,14 @@ reset_state(); while ($ARGV[0] =~ m/^-(.*)/) { my $cmd = shift @ARGV; - if ($cmd eq "-html") { - $output_mode = "html"; - @highlights = @highlights_html; - $blankline = $blankline_html; - } elsif ($cmd eq "-html5") { - $output_mode = "html5"; - @highlights = @highlights_html5; - $blankline = $blankline_html5; - } elsif ($cmd eq "-man") { + if ($cmd eq "-man") { $output_mode = "man"; @highlights = @highlights_man; $blankline = $blankline_man; - } elsif ($cmd eq "-text") { - $output_mode = "text"; - @highlights = @highlights_text; - $blankline = $blankline_text; } elsif ($cmd eq "-rst") { $output_mode = "rst"; @highlights = @highlights_rst; $blankline = $blankline_rst; - } elsif ($cmd eq "-docbook") { - $output_mode = "xml"; - @highlights = @highlights_xml; - $blankline = $blankline_xml; - } elsif ($cmd eq "-list") { - $output_mode = "list"; - @highlights = @highlights_list; - $blankline = $blankline_list; - } elsif ($cmd eq "-gnome") { - $output_mode = "gnome"; - @highlights = @highlights_gnome; - $blankline = $blankline_gnome; } elsif ($cmd eq "-none") { $output_mode = "none"; } elsif ($cmd eq "-module") { # not needed for XML, inherits from calling document @@ -670,22 +538,11 @@ sub output_highlight { # confess "output_highlight got called with no args?\n"; # } - if ($output_mode eq "html" || $output_mode eq "html5" || - $output_mode eq "xml") { - $contents = local_unescape($contents); - # convert data read & converted thru xml_escape() into &xyz; format: - $contents =~ s/\\\\\\/\&/g; - } # print STDERR "contents b4:$contents\n"; eval $dohighlight; die $@ if $@; # print STDERR "contents af:$contents\n"; -# strip whitespaces when generating html5 - if ($output_mode eq "html5") { - $contents =~ s/^\s+//; - $contents =~ s/\s+$//; - } foreach $line (split "\n", $contents) { if (! $output_preformatted) { $line =~ s/^\s*//; @@ -706,817 +563,6 @@ sub output_highlight { } } -# output sections in html -sub output_section_html(%) { - my %args = %{$_[0]}; - my $section; - - foreach $section (@{$args{'sectionlist'}}) { - print "

$section

\n"; - print "
\n"; - output_highlight($args{'sections'}{$section}); - print "
\n"; - } -} - -# output enum in html -sub output_enum_html(%) { - my %args = %{$_[0]}; - my ($parameter); - my $count; - print "

enum " . $args{'enum'} . "

\n"; - - print "enum " . $args{'enum'} . " {
\n"; - $count = 0; - foreach $parameter (@{$args{'parameterlist'}}) { - print " " . $parameter . ""; - if ($count != $#{$args{'parameterlist'}}) { - $count++; - print ",\n"; - } - print "
"; - } - print "};
\n"; - - print "

Constants

\n"; - print "
\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - print "
" . $parameter . "\n"; - print "
"; - output_highlight($args{'parameterdescs'}{$parameter}); - } - print "
\n"; - output_section_html(@_); - print "
\n"; -} - -# output typedef in html -sub output_typedef_html(%) { - my %args = %{$_[0]}; - my ($parameter); - my $count; - print "

typedef " . $args{'typedef'} . "

\n"; - - print "typedef " . $args{'typedef'} . "\n"; - output_section_html(@_); - print "
\n"; -} - -# output struct in html -sub output_struct_html(%) { - my %args = %{$_[0]}; - my ($parameter); - - print "

" . $args{'type'} . " " . $args{'struct'} . " - " . $args{'purpose'} . "

\n"; - print "" . $args{'type'} . " " . $args{'struct'} . " {
\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - if ($parameter =~ /^#/) { - print "$parameter
\n"; - next; - } - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print "    $1$parameter) ($2);
\n"; - } elsif ($type =~ m/^(.*?)\s*(:.*)/) { - # bitfield - print "    $1 $parameter$2;
\n"; - } else { - print "    $type $parameter;
\n"; - } - } - print "};
\n"; - - print "

Members

\n"; - print "
\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - ($parameter =~ /^#/) && next; - - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - print "
" . $parameter . "\n"; - print "
"; - output_highlight($args{'parameterdescs'}{$parameter_name}); - } - print "
\n"; - output_section_html(@_); - print "
\n"; -} - -# output function in html -sub output_function_html(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - my $count; - - print "

" . $args{'function'} . " - " . $args{'purpose'} . "

\n"; - print "" . $args{'functiontype'} . "\n"; - print "" . $args{'function'} . "\n"; - print "("; - $count = 0; - foreach $parameter (@{$args{'parameterlist'}}) { - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print "$1$parameter) ($2)"; - } else { - print "" . $type . " " . $parameter . ""; - } - if ($count != $#{$args{'parameterlist'}}) { - $count++; - print ",\n"; - } - } - print ")\n"; - - print "

Arguments

\n"; - print "
\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - print "
" . $parameter . "\n"; - print "
"; - output_highlight($args{'parameterdescs'}{$parameter_name}); - } - print "
\n"; - output_section_html(@_); - print "
\n"; -} - -# output DOC: block header in html -sub output_blockhead_html(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - my $count; - - foreach $section (@{$args{'sectionlist'}}) { - print "

$section

\n"; - print "
    \n"; - output_highlight($args{'sections'}{$section}); - print "
\n"; - } - print "
\n"; -} - -# output sections in html5 -sub output_section_html5(%) { - my %args = %{$_[0]}; - my $section; - - foreach $section (@{$args{'sectionlist'}}) { - print "
\n"; - print "

$section

\n"; - print "

\n"; - output_highlight($args{'sections'}{$section}); - print "

\n"; - print "
\n"; - } -} - -# output enum in html5 -sub output_enum_html5(%) { - my %args = %{$_[0]}; - my ($parameter); - my $count; - my $html5id; - - $html5id = $args{'enum'}; - $html5id =~ s/[^a-zA-Z0-9\-]+/_/g; - print "
"; - print "

enum " . $args{'enum'} . "

\n"; - print "
    \n"; - print "
  1. "; - print "enum "; - print "" . $args{'enum'} . " {"; - print "
  2. \n"; - $count = 0; - foreach $parameter (@{$args{'parameterlist'}}) { - print "
  3. "; - print "" . $parameter . ""; - if ($count != $#{$args{'parameterlist'}}) { - $count++; - print ","; - } - print "
  4. \n"; - } - print "
  5. };
  6. \n"; - print "
\n"; - - print "
\n"; - print "

Constants

\n"; - print "
\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - print "
" . $parameter . "
\n"; - print "
"; - output_highlight($args{'parameterdescs'}{$parameter}); - print "
\n"; - } - print "
\n"; - print "
\n"; - output_section_html5(@_); - print "
\n"; -} - -# output typedef in html5 -sub output_typedef_html5(%) { - my %args = %{$_[0]}; - my ($parameter); - my $count; - my $html5id; - - $html5id = $args{'typedef'}; - $html5id =~ s/[^a-zA-Z0-9\-]+/_/g; - print "
\n"; - print "

typedef " . $args{'typedef'} . "

\n"; - - print "
    \n"; - print "
  1. "; - print "typedef "; - print "" . $args{'typedef'} . ""; - print "
  2. \n"; - print "
\n"; - output_section_html5(@_); - print "
\n"; -} - -# output struct in html5 -sub output_struct_html5(%) { - my %args = %{$_[0]}; - my ($parameter); - my $html5id; - - $html5id = $args{'struct'}; - $html5id =~ s/[^a-zA-Z0-9\-]+/_/g; - print "
\n"; - print "
\n"; - print "

" . $args{'type'} . " " . $args{'struct'} . "

"; - print "

". $args{'purpose'} . "

\n"; - print "
\n"; - print "
    \n"; - print "
  1. "; - print "" . $args{'type'} . " "; - print "" . $args{'struct'} . " {"; - print "
  2. \n"; - foreach $parameter (@{$args{'parameterlist'}}) { - print "
  3. "; - if ($parameter =~ /^#/) { - print "" . $parameter ."\n"; - print "
  4. \n"; - next; - } - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print "$1 "; - print "$parameter"; - print ") "; - print "($2);"; - } elsif ($type =~ m/^(.*?)\s*(:.*)/) { - # bitfield - print "$1 "; - print "$parameter"; - print "$2;"; - } else { - print "$type "; - print "$parameter;"; - } - print "\n"; - } - print "
  5. };
  6. \n"; - print "
\n"; - - print "
\n"; - print "

Members

\n"; - print "
\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - ($parameter =~ /^#/) && next; - - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - print "
" . $parameter . "
\n"; - print "
"; - output_highlight($args{'parameterdescs'}{$parameter_name}); - print "
\n"; - } - print "
\n"; - print "
\n"; - output_section_html5(@_); - print "
\n"; -} - -# output function in html5 -sub output_function_html5(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - my $count; - my $html5id; - - $html5id = $args{'function'}; - $html5id =~ s/[^a-zA-Z0-9\-]+/_/g; - print "
\n"; - print "
\n"; - print "

" . $args{'function'} . "

"; - print "

" . $args{'purpose'} . "

\n"; - print "
\n"; - print "
    \n"; - print "
  1. "; - print "" . $args{'functiontype'} . " "; - print "" . $args{'function'} . " ("; - print "
  2. "; - $count = 0; - foreach $parameter (@{$args{'parameterlist'}}) { - print "
  3. "; - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print "$1 "; - print "$parameter"; - print ") "; - print "($2)"; - } else { - print "$type "; - print "$parameter"; - } - if ($count != $#{$args{'parameterlist'}}) { - $count++; - print ","; - } - print "
  4. \n"; - } - print "
  5. )
  6. \n"; - print "
\n"; - - print "
\n"; - print "

Arguments

\n"; - print "

\n"; - print "

\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - print "
" . $parameter . "
\n"; - print "
"; - output_highlight($args{'parameterdescs'}{$parameter_name}); - print "
\n"; - } - print "
\n"; - print "
\n"; - output_section_html5(@_); - print "
\n"; -} - -# output DOC: block header in html5 -sub output_blockhead_html5(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - my $count; - my $html5id; - - foreach $section (@{$args{'sectionlist'}}) { - $html5id = $section; - $html5id =~ s/[^a-zA-Z0-9\-]+/_/g; - print "
\n"; - print "

$section

\n"; - print "

\n"; - output_highlight($args{'sections'}{$section}); - print "

\n"; - } - print "
\n"; -} - -sub output_section_xml(%) { - my %args = %{$_[0]}; - my $section; - # print out each section - $lineprefix=" "; - foreach $section (@{$args{'sectionlist'}}) { - print "\n"; - print "$section\n"; - if ($section =~ m/EXAMPLE/i) { - print "\n"; - $output_preformatted = 1; - } else { - print "\n"; - } - output_highlight($args{'sections'}{$section}); - $output_preformatted = 0; - if ($section =~ m/EXAMPLE/i) { - print "\n"; - } else { - print "\n"; - } - print "\n"; - } -} - -# output function in XML DocBook -sub output_function_xml(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - my $count; - my $id; - - $id = "API-" . $args{'function'}; - $id =~ s/[^A-Za-z0-9]/-/g; - - print "\n"; - print "\n"; - print " LINUX\n"; - print " Kernel Hackers Manual\n"; - print " $man_date\n"; - print "\n"; - print "\n"; - print " " . $args{'function'} . "\n"; - print " 9\n"; - print " " . $kernelversion . "\n"; - print "\n"; - print "\n"; - print " " . $args{'function'} . "\n"; - print " \n"; - print " "; - output_highlight ($args{'purpose'}); - print " \n"; - print "\n"; - - print "\n"; - print " Synopsis\n"; - print " \n"; - print " " . $args{'functiontype'} . " "; - print "" . $args{'function'} . " \n"; - - $count = 0; - if ($#{$args{'parameterlist'}} >= 0) { - foreach $parameter (@{$args{'parameterlist'}}) { - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print " $1$parameter)\n"; - print " $2\n"; - } else { - print " " . $type; - print " $parameter\n"; - } - } - } else { - print " \n"; - } - print " \n"; - print "\n"; - - # print parameters - print "\n Arguments\n"; - if ($#{$args{'parameterlist'}} >= 0) { - print " \n"; - foreach $parameter (@{$args{'parameterlist'}}) { - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - $type = $args{'parametertypes'}{$parameter}; - - print " \n $type $parameter\n"; - print " \n \n"; - $lineprefix=" "; - output_highlight($args{'parameterdescs'}{$parameter_name}); - print " \n \n \n"; - } - print " \n"; - } else { - print " \n None\n \n"; - } - print "\n"; - - output_section_xml(@_); - print "\n\n"; -} - -# output struct in XML DocBook -sub output_struct_xml(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - my $id; - - $id = "API-struct-" . $args{'struct'}; - $id =~ s/[^A-Za-z0-9]/-/g; - - print "\n"; - print "\n"; - print " LINUX\n"; - print " Kernel Hackers Manual\n"; - print " $man_date\n"; - print "\n"; - print "\n"; - print " " . $args{'type'} . " " . $args{'struct'} . "\n"; - print " 9\n"; - print " " . $kernelversion . "\n"; - print "\n"; - print "\n"; - print " " . $args{'type'} . " " . $args{'struct'} . "\n"; - print " \n"; - print " "; - output_highlight ($args{'purpose'}); - print " \n"; - print "\n"; - - print "\n"; - print " Synopsis\n"; - print " \n"; - print $args{'type'} . " " . $args{'struct'} . " {\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - if ($parameter =~ /^#/) { - my $prm = $parameter; - # convert data read & converted thru xml_escape() into &xyz; format: - # This allows us to have #define macros interspersed in a struct. - $prm =~ s/\\\\\\/\&/g; - print "$prm\n"; - next; - } - - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - defined($args{'parameterdescs'}{$parameter_name}) || next; - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print " $1 $parameter) ($2);\n"; - } elsif ($type =~ m/^(.*?)\s*(:.*)/) { - # bitfield - print " $1 $parameter$2;\n"; - } else { - print " " . $type . " " . $parameter . ";\n"; - } - } - print "};"; - print " \n"; - print "\n"; - - print " \n"; - print " Members\n"; - - if ($#{$args{'parameterlist'}} >= 0) { - print " \n"; - foreach $parameter (@{$args{'parameterlist'}}) { - ($parameter =~ /^#/) && next; - - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - defined($args{'parameterdescs'}{$parameter_name}) || next; - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - $type = $args{'parametertypes'}{$parameter}; - print " "; - print " $type $parameter\n"; - print " \n"; - output_highlight($args{'parameterdescs'}{$parameter_name}); - print " \n"; - print " \n"; - } - print " \n"; - } else { - print " \n None\n \n"; - } - print " \n"; - - output_section_xml(@_); - - print "\n\n"; -} - -# output enum in XML DocBook -sub output_enum_xml(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - my $count; - my $id; - - $id = "API-enum-" . $args{'enum'}; - $id =~ s/[^A-Za-z0-9]/-/g; - - print "\n"; - print "\n"; - print " LINUX\n"; - print " Kernel Hackers Manual\n"; - print " $man_date\n"; - print "\n"; - print "\n"; - print " enum " . $args{'enum'} . "\n"; - print " 9\n"; - print " " . $kernelversion . "\n"; - print "\n"; - print "\n"; - print " enum " . $args{'enum'} . "\n"; - print " \n"; - print " "; - output_highlight ($args{'purpose'}); - print " \n"; - print "\n"; - - print "\n"; - print " Synopsis\n"; - print " \n"; - print "enum " . $args{'enum'} . " {\n"; - $count = 0; - foreach $parameter (@{$args{'parameterlist'}}) { - print " $parameter"; - if ($count != $#{$args{'parameterlist'}}) { - $count++; - print ","; - } - print "\n"; - } - print "};"; - print " \n"; - print "\n"; - - print "\n"; - print " Constants\n"; - print " \n"; - foreach $parameter (@{$args{'parameterlist'}}) { - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - print " "; - print " $parameter\n"; - print " \n"; - output_highlight($args{'parameterdescs'}{$parameter_name}); - print " \n"; - print " \n"; - } - print " \n"; - print "\n"; - - output_section_xml(@_); - - print "\n\n"; -} - -# output typedef in XML DocBook -sub output_typedef_xml(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - my $id; - - $id = "API-typedef-" . $args{'typedef'}; - $id =~ s/[^A-Za-z0-9]/-/g; - - print "\n"; - print "\n"; - print " LINUX\n"; - print " Kernel Hackers Manual\n"; - print " $man_date\n"; - print "\n"; - print "\n"; - print " typedef " . $args{'typedef'} . "\n"; - print " 9\n"; - print "\n"; - print "\n"; - print " typedef " . $args{'typedef'} . "\n"; - print " \n"; - print " "; - output_highlight ($args{'purpose'}); - print " \n"; - print "\n"; - - print "\n"; - print " Synopsis\n"; - print " typedef " . $args{'typedef'} . ";\n"; - print "\n"; - - output_section_xml(@_); - - print "\n\n"; -} - -# output in XML DocBook -sub output_blockhead_xml(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - my $count; - - my $id = $args{'module'}; - $id =~ s/[^A-Za-z0-9]/-/g; - - # print out each section - $lineprefix=" "; - foreach $section (@{$args{'sectionlist'}}) { - if (!$args{'content-only'}) { - print "\n $section\n"; - } - if ($section =~ m/EXAMPLE/i) { - print "\n"; - $output_preformatted = 1; - } else { - print "\n"; - } - output_highlight($args{'sections'}{$section}); - $output_preformatted = 0; - if ($section =~ m/EXAMPLE/i) { - print "\n"; - } else { - print ""; - } - if (!$args{'content-only'}) { - print "\n\n"; - } - } - - print "\n\n"; -} - -# output in XML DocBook -sub output_function_gnome { - my %args = %{$_[0]}; - my ($parameter, $section); - my $count; - my $id; - - $id = $args{'module'} . "-" . $args{'function'}; - $id =~ s/[^A-Za-z0-9]/-/g; - - print "\n"; - print " " . $args{'function'} . "\n"; - - print " \n"; - print " " . $args{'functiontype'} . " "; - print "" . $args{'function'} . " "; - print "\n"; - - $count = 0; - if ($#{$args{'parameterlist'}} >= 0) { - foreach $parameter (@{$args{'parameterlist'}}) { - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print " $1 $parameter)\n"; - print " $2\n"; - } else { - print " " . $type; - print " $parameter\n"; - } - } - } else { - print " \n"; - } - print " \n"; - if ($#{$args{'parameterlist'}} >= 0) { - print " \n"; - print "\n"; - print "\n"; - print "\n"; - print "\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - print " $parameter\n"; - print " \n"; - $lineprefix=" "; - output_highlight($args{'parameterdescs'}{$parameter_name}); - print " \n"; - } - print " \n"; - } else { - print " \n None\n \n"; - } - - # print out each section - $lineprefix=" "; - foreach $section (@{$args{'sectionlist'}}) { - print "\n $section\n"; - if ($section =~ m/EXAMPLE/i) { - print "\n"; - $output_preformatted = 1; - } else { - } - print "\n"; - output_highlight($args{'sections'}{$section}); - $output_preformatted = 0; - print "\n"; - if ($section =~ m/EXAMPLE/i) { - print "\n"; - } else { - } - print " \n"; - } - - print "\n\n"; -} - ## # output function in man sub output_function_man(%) { @@ -1694,161 +740,6 @@ sub output_blockhead_man(%) { } } -## -# output in text -sub output_function_text(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - my $start; - - print "Name:\n\n"; - print $args{'function'} . " - " . $args{'purpose'} . "\n"; - - print "\nSynopsis:\n\n"; - if ($args{'functiontype'} ne "") { - $start = $args{'functiontype'} . " " . $args{'function'} . " ("; - } else { - $start = $args{'function'} . " ("; - } - print $start; - - my $count = 0; - foreach my $parameter (@{$args{'parameterlist'}}) { - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print $1 . $parameter . ") (" . $2; - } else { - print $type . " " . $parameter; - } - if ($count != $#{$args{'parameterlist'}}) { - $count++; - print ",\n"; - print " " x length($start); - } else { - print ");\n\n"; - } - } - - print "Arguments:\n\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - print $parameter . "\n\t" . $args{'parameterdescs'}{$parameter_name} . "\n"; - } - output_section_text(@_); -} - -#output sections in text -sub output_section_text(%) { - my %args = %{$_[0]}; - my $section; - - print "\n"; - foreach $section (@{$args{'sectionlist'}}) { - print "$section:\n\n"; - output_highlight($args{'sections'}{$section}); - } - print "\n\n"; -} - -# output enum in text -sub output_enum_text(%) { - my %args = %{$_[0]}; - my ($parameter); - my $count; - print "Enum:\n\n"; - - print "enum " . $args{'enum'} . " - " . $args{'purpose'} . "\n\n"; - print "enum " . $args{'enum'} . " {\n"; - $count = 0; - foreach $parameter (@{$args{'parameterlist'}}) { - print "\t$parameter"; - if ($count != $#{$args{'parameterlist'}}) { - $count++; - print ","; - } - print "\n"; - } - print "};\n\n"; - - print "Constants:\n\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - print "$parameter\n\t"; - print $args{'parameterdescs'}{$parameter} . "\n"; - } - - output_section_text(@_); -} - -# output typedef in text -sub output_typedef_text(%) { - my %args = %{$_[0]}; - my ($parameter); - my $count; - print "Typedef:\n\n"; - - print "typedef " . $args{'typedef'} . " - " . $args{'purpose'} . "\n"; - output_section_text(@_); -} - -# output struct as text -sub output_struct_text(%) { - my %args = %{$_[0]}; - my ($parameter); - - print $args{'type'} . " " . $args{'struct'} . " - " . $args{'purpose'} . "\n\n"; - print $args{'type'} . " " . $args{'struct'} . " {\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - if ($parameter =~ /^#/) { - print "$parameter\n"; - next; - } - - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print "\t$1 $parameter) ($2);\n"; - } elsif ($type =~ m/^(.*?)\s*(:.*)/) { - # bitfield - print "\t$1 $parameter$2;\n"; - } else { - print "\t" . $type . " " . $parameter . ";\n"; - } - } - print "};\n\n"; - - print "Members:\n\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - ($parameter =~ /^#/) && next; - - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - print "$parameter\n\t"; - print $args{'parameterdescs'}{$parameter_name} . "\n"; - } - print "\n"; - output_section_text(@_); -} - -sub output_blockhead_text(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - - foreach $section (@{$args{'sectionlist'}}) { - print " $section:\n"; - print " -> "; - output_highlight($args{'sections'}{$section}); - } -} - ## # output in restructured text # @@ -2083,44 +974,6 @@ sub output_struct_rst(%) { output_section_rst(@_); } - -## list mode output functions - -sub output_function_list(%) { - my %args = %{$_[0]}; - - print $args{'function'} . "\n"; -} - -# output enum in list -sub output_enum_list(%) { - my %args = %{$_[0]}; - print $args{'enum'} . "\n"; -} - -# output typedef in list -sub output_typedef_list(%) { - my %args = %{$_[0]}; - print $args{'typedef'} . "\n"; -} - -# output struct as list -sub output_struct_list(%) { - my %args = %{$_[0]}; - - print $args{'struct'} . "\n"; -} - -sub output_blockhead_list(%) { - my %args = %{$_[0]}; - my ($parameter, $section); - - foreach $section (@{$args{'sectionlist'}}) { - print "DOC: $section\n"; - } -} - - ## none mode output functions sub output_function_none(%) { @@ -2827,7 +1680,7 @@ sub process_proto_type($$) { # just before actual output; (this is done by local_unescape()) sub xml_escape($) { my $text = shift; - if (($output_mode eq "text") || ($output_mode eq "man")) { + if ($output_mode eq "man") { return $text; } $text =~ s/\&/\\\\\\amp;/g; @@ -2839,7 +1692,7 @@ sub xml_escape($) { # xml_unescape: reverse the effects of xml_escape sub xml_unescape($) { my $text = shift; - if (($output_mode eq "text") || ($output_mode eq "man")) { + if ($output_mode eq "man") { return $text; } $text =~ s/\\\\\\amp;/\&/g; @@ -2852,7 +1705,7 @@ sub xml_unescape($) { # local escape strings look like: '\\\\menmonic:' (that's 4 backslashes) sub local_unescape($) { my $text = shift; - if (($output_mode eq "text") || ($output_mode eq "man")) { + if ($output_mode eq "man") { return $text; } $text =~ s/\\\\\\\\lt:/\n"; - print " \n"; - print " \n"; - print " ${orig_file}\n"; - print " \n"; - print " \n"; - print " Document generation inconsistency\n"; - print " \n"; - print " \n"; - print " \n"; - print " \n"; - print " Oops\n"; - print " \n"; - print " \n"; - print " \n"; - print " The template for this document tried to insert\n"; - print " the structured comment from the file\n"; - print " ${orig_file} at this point,\n"; - print " but none was found.\n"; - print " This dummy section is inserted to allow\n"; - print " generation to continue.\n"; - print " \n"; - print " \n"; - print " \n"; - print "\n"; - } } } -- cgit v1.2.3-59-g8ed1b From b031ac4e7ddcd16e34cbc4fa33e340857a99d181 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 18 Dec 2017 10:30:10 -0200 Subject: scripts: kernel-doc: improve argument handling Right now, if one uses "--rst" instead of "-rst", it just ignore the argument and produces a man page. Change the logic to accept both "-cmd" and "--cmd". Also, if "cmd" doesn't exist, print the usage information and exit. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index c8ad05eb3e5e..11aec7469776 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -391,47 +391,51 @@ my $undescribed = "-- undescribed --"; reset_state(); -while ($ARGV[0] =~ m/^-(.*)/) { - my $cmd = shift @ARGV; - if ($cmd eq "-man") { +while ($ARGV[0] =~ m/^--?(.*)/) { + my $cmd = $1; + shift @ARGV; + if ($cmd eq "man") { $output_mode = "man"; @highlights = @highlights_man; $blankline = $blankline_man; - } elsif ($cmd eq "-rst") { + } elsif ($cmd eq "rst") { $output_mode = "rst"; @highlights = @highlights_rst; $blankline = $blankline_rst; - } elsif ($cmd eq "-none") { + } elsif ($cmd eq "none") { $output_mode = "none"; - } elsif ($cmd eq "-module") { # not needed for XML, inherits from calling document + } elsif ($cmd eq "module") { # not needed for XML, inherits from calling document $modulename = shift @ARGV; - } elsif ($cmd eq "-function") { # to only output specific functions + } elsif ($cmd eq "function") { # to only output specific functions $output_selection = OUTPUT_INCLUDE; $function = shift @ARGV; $function_table{$function} = 1; - } elsif ($cmd eq "-nofunction") { # output all except specific functions + } elsif ($cmd eq "nofunction") { # output all except specific functions $output_selection = OUTPUT_EXCLUDE; $function = shift @ARGV; $function_table{$function} = 1; - } elsif ($cmd eq "-export") { # only exported symbols + } elsif ($cmd eq "export") { # only exported symbols $output_selection = OUTPUT_EXPORTED; %function_table = (); - } elsif ($cmd eq "-internal") { # only non-exported symbols + } elsif ($cmd eq "internal") { # only non-exported symbols $output_selection = OUTPUT_INTERNAL; %function_table = (); - } elsif ($cmd eq "-export-file") { + } elsif ($cmd eq "export-file") { my $file = shift @ARGV; push(@export_file_list, $file); - } elsif ($cmd eq "-v") { + } elsif ($cmd eq "v") { $verbose = 1; - } elsif (($cmd eq "-h") || ($cmd eq "--help")) { + } elsif (($cmd eq "h") || ($cmd eq "help")) { usage(); - } elsif ($cmd eq '-no-doc-sections') { + } elsif ($cmd eq 'no-doc-sections') { $no_doc_sections = 1; - } elsif ($cmd eq '-enable-lineno') { + } elsif ($cmd eq 'enable-lineno') { $enable_lineno = 1; - } elsif ($cmd eq '-show-not-found') { + } elsif ($cmd eq 'show-not-found') { $show_not_found = 1; + } else { + # Unknown argument + usage(); } } -- cgit v1.2.3-59-g8ed1b From bdfe2be34b37d988a525d5559fe132728510735a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 18 Dec 2017 10:30:11 -0200 Subject: scripts: kernel-doc: change default to ReST format Right now, if kernel-doc is called without arguments, it defaults to man pages. IMO, it makes more sense to default to ReST, as this is the output that it is most used nowadays, and it easier to check if everything got parsed fine on an enriched text mode format. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 11aec7469776..e417d93575b9 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -268,12 +268,12 @@ my $kernelversion; my $dohighlight = ""; my $verbose = 0; -my $output_mode = "man"; +my $output_mode = "rst"; my $output_preformatted = 0; my $no_doc_sections = 0; my $enable_lineno = 0; -my @highlights = @highlights_man; -my $blankline = $blankline_man; +my @highlights = @highlights_rst; +my $blankline = $blankline_rst; my $modulename = "Kernel API"; use constant { -- cgit v1.2.3-59-g8ed1b From 7c9aa0157ef4b4cc28c98b08a971dc8344e64aab Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 18 Dec 2017 10:30:12 -0200 Subject: scripts: kernel-doc: replace tabs by spaces Sphinx has a hard time dealing with tabs, causing it to misinterpret paragraph continuation. As we're now mainly focused on supporting ReST output, replace tabs by spaces, in order to avoid troubles when the output is parsed by Sphinx. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index e417d93575b9..05aadac0612a 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1579,7 +1579,7 @@ sub tracepoint_munge($) { sub syscall_munge() { my $void = 0; - $prototype =~ s@[\r\n\t]+@ @gos; # strip newlines/CR's/tabs + $prototype =~ s@[\r\n]+@ @gos; # strip newlines/CR's ## if ($prototype =~ m/SYSCALL_DEFINE0\s*\(\s*(a-zA-Z0-9_)*\s*\)/) { if ($prototype =~ m/SYSCALL_DEFINE0/) { $void = 1; @@ -1778,6 +1778,8 @@ sub process_file($) { while (s/\\\s*$//) { $_ .= ; } + # Replace tabs by spaces + while ($_ =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {}; if ($state == STATE_NORMAL) { if (/$doc_start/o) { $state = STATE_NAME; # next line is always the function name @@ -1877,8 +1879,7 @@ sub process_file($) { $in_purpose = 0; $contents = $newcontents; $new_start_line = $.; - while ((substr($contents, 0, 1) eq " ") || - substr($contents, 0, 1) eq "\t") { + while (substr($contents, 0, 1) eq " ") { $contents = substr($contents, 1); } if ($contents ne "") { @@ -1947,8 +1948,7 @@ sub process_file($) { $contents = $2; $new_start_line = $.; if ($contents ne "") { - while ((substr($contents, 0, 1) eq " ") || - substr($contents, 0, 1) eq "\t") { + while (substr($contents, 0, 1) eq " ") { $contents = substr($contents, 1); } $contents .= "\n"; -- cgit v1.2.3-59-g8ed1b From 8ad72163165265b686902c182c1b4a913e738a81 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 18 Dec 2017 10:30:13 -0200 Subject: scripts: kernel-doc: parse next structs/unions There are several places within the Kernel tree with nested structs/unions, like this one: struct ingenic_cgu_clk_info { const char *name; enum { CGU_CLK_NONE = 0, CGU_CLK_EXT = BIT(0), CGU_CLK_PLL = BIT(1), CGU_CLK_GATE = BIT(2), CGU_CLK_MUX = BIT(3), CGU_CLK_MUX_GLITCHFREE = BIT(4), CGU_CLK_DIV = BIT(5), CGU_CLK_FIXDIV = BIT(6), CGU_CLK_CUSTOM = BIT(7), } type; int parents[4]; union { struct ingenic_cgu_pll_info pll; struct { struct ingenic_cgu_gate_info gate; struct ingenic_cgu_mux_info mux; struct ingenic_cgu_div_info div; struct ingenic_cgu_fixdiv_info fixdiv; }; struct ingenic_cgu_custom_info custom; }; }; Currently, such struct is documented as: **Definition** :: struct ingenic_cgu_clk_info { const char * name; }; **Members** ``name`` name of the clock With is obvioulsy wrong. It also generates an error: drivers/clk/ingenic/cgu.h:169: warning: No description found for parameter 'enum' However, there's nothing wrong with this kernel-doc markup: everything is documented there. It makes sense to document all fields there. So, add a way for the core to parse those structs. With this patch, all documented fields will properly generate documentation. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Jonathan Corbet --- Documentation/doc-guide/kernel-doc.rst | 46 +++++++++++++ scripts/kernel-doc | 121 ++++++++++++++++++--------------- 2 files changed, 114 insertions(+), 53 deletions(-) (limited to 'scripts') diff --git a/Documentation/doc-guide/kernel-doc.rst b/Documentation/doc-guide/kernel-doc.rst index 14c226e8154f..722d4525f7cf 100644 --- a/Documentation/doc-guide/kernel-doc.rst +++ b/Documentation/doc-guide/kernel-doc.rst @@ -281,6 +281,52 @@ comment block. The kernel-doc data structure comments describe each member of the structure, in order, with the member descriptions. +Nested structs/unions +~~~~~~~~~~~~~~~~~~~~~ + +It is possible to document nested structs unions, like:: + + /** + * struct nested_foobar - a struct with nested unions and structs + * @arg1: - first argument of anonymous union/anonymous struct + * @arg2: - second argument of anonymous union/anonymous struct + * @arg3: - third argument of anonymous union/anonymous struct + * @arg4: - fourth argument of anonymous union/anonymous struct + * @bar.st1.arg1 - first argument of struct st1 on union bar + * @bar.st1.arg2 - second argument of struct st1 on union bar + * @bar.st2.arg1 - first argument of struct st2 on union bar + * @bar.st2.arg2 - second argument of struct st2 on union bar + struct nested_foobar { + /* Anonymous union/struct*/ + union { + struct { + int arg1; + int arg2; + } + struct { + void *arg3; + int arg4; + } + } + union { + struct { + int arg1; + int arg2; + } st1; + struct { + void *arg1; + int arg2; + } st2; + } bar; + }; + +.. note:: + + #) When documenting nested structs or unions, if the struct/union ``foo`` + is named, the argument ``bar`` inside it should be documented as + ``@foo.bar:`` + #) When the nested struct/union is anonymous, the argument ``bar`` on it + should be documented as ``@bar:`` Typedef documentation --------------------- diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 05aadac0612a..b0eb1cd6afbe 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -211,7 +211,7 @@ my $anon_struct_union = 0; my $type_constant = '\b``([^\`]+)``\b'; my $type_constant2 = '\%([-_\w]+)'; my $type_func = '(\w+)\(\)'; -my $type_param = '\@(\w+(\.\.\.)?)'; +my $type_param = '\@(\w*(\.\w+)*(\.\.\.)?)'; my $type_fp_param = '\@(\w+)\(\)'; # Special RST handling for func ptr params my $type_env = '(\$\w+)'; my $type_enum = '\&(enum\s*([_\w]+))'; @@ -670,32 +670,12 @@ sub output_struct_man(%) { print ".SH NAME\n"; print $args{'type'} . " " . $args{'struct'} . " \\- " . $args{'purpose'} . "\n"; + my $declaration = $args{'definition'}; + $declaration =~ s/\t/ /g; + $declaration =~ s/\n/"\n.br\n.BI \"/g; print ".SH SYNOPSIS\n"; print $args{'type'} . " " . $args{'struct'} . " {\n.br\n"; - - foreach my $parameter (@{$args{'parameterlist'}}) { - if ($parameter =~ /^#/) { - print ".BI \"$parameter\"\n.br\n"; - next; - } - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print ".BI \" " . $1 . "\" " . $parameter . " \") (" . $2 . ")" . "\"\n;\n"; - } elsif ($type =~ m/^(.*?)\s*(:.*)/) { - # bitfield - print ".BI \" " . $1 . "\ \" " . $parameter . $2 . " \"" . "\"\n;\n"; - } else { - $type =~ s/([^\*])$/$1 /; - print ".BI \" " . $type . "\" " . $parameter . " \"" . "\"\n;\n"; - } - print "\n.br\n"; - } - print "};\n.br\n"; + print ".BI \"$declaration\n};\n.br\n\n"; print ".SH Members\n"; foreach $parameter (@{$args{'parameterlist'}}) { @@ -933,29 +913,9 @@ sub output_struct_rst(%) { print "**Definition**\n\n"; print "::\n\n"; - print " " . $args{'type'} . " " . $args{'struct'} . " {\n"; - foreach $parameter (@{$args{'parameterlist'}}) { - if ($parameter =~ /^#/) { - print " " . "$parameter\n"; - next; - } - - my $parameter_name = $parameter; - $parameter_name =~ s/\[.*//; - - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; - $type = $args{'parametertypes'}{$parameter}; - if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { - # pointer-to-function - print " $1 $parameter) ($2);\n"; - } elsif ($type =~ m/^(.*?)\s*(:.*)/) { - # bitfield - print " $1 $parameter$2;\n"; - } else { - print " " . $type . " " . $parameter . ";\n"; - } - } - print " };\n\n"; + my $declaration = $args{'definition'}; + $declaration =~ s/\t/ /g; + print " " . $args{'type'} . " " . $args{'struct'} . " {\n$declaration };\n\n"; print "**Members**\n\n"; $lineprefix = " "; @@ -1050,16 +1010,11 @@ sub dump_struct($$) { $declaration_name = $2; my $members = $3; - # ignore embedded structs or unions - $members =~ s/({.*})//g; - $nested = $1; - # ignore members marked private: $members =~ s/\/\*\s*private:.*?\/\*\s*public:.*?\*\///gosi; $members =~ s/\/\*\s*private:.*//gosi; # strip comments: $members =~ s/\/\*.*?\*\///gos; - $nested =~ s/\/\*.*?\*\///gos; # strip attributes $members =~ s/__attribute__\s*\(\([a-z,_\*\s\(\)]*\)\)//i; $members =~ s/__aligned\s*\([^;]*\)//gos; @@ -1073,13 +1028,73 @@ sub dump_struct($$) { # replace DECLARE_KFIFO_PTR $members =~ s/DECLARE_KFIFO_PTR\s*\(([^,)]+),\s*([^,)]+)\)/$2 \*$1/gos; + my $declaration = $members; + + # Split nested struct/union elements as newer ones + my $cont = 1; + while ($cont) { + $cont = 0; + while ($members =~ m/(struct|union)([^{};]+){([^{}]*)}([^{}\;]*)\;/) { + my $newmember = "$1 $4;"; + my $id = $4; + my $content = $3; + $id =~ s/[:\[].*//; + $id =~ s/^\*+//; + foreach my $arg (split /;/, $content) { + next if ($arg =~ m/^\s*$/); + my $type = $arg; + my $name = $arg; + $type =~ s/\s\S+$//; + $name =~ s/.*\s//; + $name =~ s/[:\[].*//; + $name =~ s/^\*+//; + next if (($name =~ m/^\s*$/)); + if ($id =~ m/^\s*$/) { + # anonymous struct/union + $newmember .= "$type $name;"; + } else { + $newmember .= "$type $id.$name;"; + } + } + $members =~ s/(struct|union)([^{};]+){([^{}]*)}([^{}\;]*)\;/$newmember/; + $cont = 1; + }; + }; + + # Ignore other nested elements, like enums + $members =~ s/({[^\{\}]*})//g; + $nested = $decl_type; + $nested =~ s/\/\*.*?\*\///gos; + create_parameterlist($members, ';', $file); check_sections($file, $declaration_name, $decl_type, $sectcheck, $struct_actual, $nested); + # Adjust declaration for better display + $declaration =~ s/([{;])/$1\n/g; + $declaration =~ s/}\s+;/};/g; + # Better handle inlined enums + do {} while ($declaration =~ s/(enum\s+{[^}]+),([^\n])/$1,\n$2/); + + my @def_args = split /\n/, $declaration; + my $level = 1; + $declaration = ""; + foreach my $clause (@def_args) { + $clause =~ s/^\s+//; + $clause =~ s/\s+$//; + $clause =~ s/\s+/ /; + next if (!$clause); + $level-- if ($clause =~ m/(})/ && $level > 1); + if (!($clause =~ m/^\s*#/)) { + $declaration .= "\t" x $level; + } + $declaration .= "\t" . $clause . "\n"; + $level++ if ($clause =~ m/({)/ && !($clause =~m/}/)); + } output_declaration($declaration_name, 'struct', {'struct' => $declaration_name, 'module' => $modulename, + 'definition' => $declaration, 'parameterlist' => \@parameterlist, 'parameterdescs' => \%parameterdescs, 'parametertypes' => \%parametertypes, -- cgit v1.2.3-59-g8ed1b From 1081de2d2f9179d7280926e37b7b22b4f2fb32e6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 18 Dec 2017 10:30:14 -0200 Subject: scripts: kernel-doc: get rid of $nested parameter The check_sections() function has a $nested parameter, meant to identify when a nested struct is present. As we now have a logic that handles it, get rid of such parameter. Suggested-by: Markus Heiser Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index b0eb1cd6afbe..fadb832733d9 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1003,7 +1003,6 @@ sub dump_union($$) { sub dump_struct($$) { my $x = shift; my $file = shift; - my $nested; if ($x =~ /(struct|union)\s+(\w+)\s*{(.*)}/) { my $decl_type = $1; @@ -1063,11 +1062,9 @@ sub dump_struct($$) { # Ignore other nested elements, like enums $members =~ s/({[^\{\}]*})//g; - $nested = $decl_type; - $nested =~ s/\/\*.*?\*\///gos; create_parameterlist($members, ';', $file); - check_sections($file, $declaration_name, $decl_type, $sectcheck, $struct_actual, $nested); + check_sections($file, $declaration_name, $decl_type, $sectcheck, $struct_actual); # Adjust declaration for better display $declaration =~ s/([{;])/$1\n/g; @@ -1372,8 +1369,8 @@ sub push_parameter($$$) { $parametertypes{$param} = $type; } -sub check_sections($$$$$$) { - my ($file, $decl_name, $decl_type, $sectcheck, $prmscheck, $nested) = @_; +sub check_sections($$$$$) { + my ($file, $decl_name, $decl_type, $sectcheck, $prmscheck) = @_; my @sects = split ' ', $sectcheck; my @prms = split ' ', $prmscheck; my $err; @@ -1407,14 +1404,6 @@ sub check_sections($$$$$$) { "'$sects[$sx]' " . "description in '$decl_name'\n"; ++$warnings; - } else { - if ($nested !~ m/\Q$sects[$sx]\E/) { - print STDERR "${file}:$.: warning: " . - "Excess $decl_type member " . - "'$sects[$sx]' " . - "description in '$decl_name'\n"; - ++$warnings; - } } } } @@ -1525,7 +1514,7 @@ sub dump_function($$) { } my $prms = join " ", @parameterlist; - check_sections($file, $declaration_name, "function", $sectcheck, $prms, ""); + check_sections($file, $declaration_name, "function", $sectcheck, $prms); # This check emits a lot of warnings at the moment, because many # functions don't have a 'Return' doc section. So until the number -- cgit v1.2.3-59-g8ed1b From 151c468b44a89a9f3173ab8575690014b7249893 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 18 Dec 2017 10:30:15 -0200 Subject: scripts: kernel-doc: print the declaration name on warnings The logic at create_parameterlist()'s ancillary push_parameter() function has already a way to output the declaration name, with would help to discover what declaration is missing. However, currently, the logic is utterly broken, as it uses the var $type with a wrong meaning. With the current code, it will never print anything. I suspect that originally it was using the second argument of output_declaration(). I opted to not rely on a globally defined $declaration_name, but, instead, to pass it explicitly as a parameter. While here, I removed a unaligned check for !$anon_struct_union. This is not needed, as, if $anon_struct_union is not zero, $parameterdescs{$param} will be defined. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index fadb832733d9..c97b89f47795 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1063,7 +1063,7 @@ sub dump_struct($$) { # Ignore other nested elements, like enums $members =~ s/({[^\{\}]*})//g; - create_parameterlist($members, ';', $file); + create_parameterlist($members, ';', $file, $declaration_name); check_sections($file, $declaration_name, $decl_type, $sectcheck, $struct_actual); # Adjust declaration for better display @@ -1172,7 +1172,7 @@ sub dump_typedef($$) { $declaration_name = $2; my $args = $3; - create_parameterlist($args, ',', $file); + create_parameterlist($args, ',', $file, $declaration_name); output_declaration($declaration_name, 'function', @@ -1221,10 +1221,11 @@ sub save_struct_actual($) { $struct_actual = $struct_actual . $actual . " "; } -sub create_parameterlist($$$) { +sub create_parameterlist($$$$) { my $args = shift; my $splitter = shift; my $file = shift; + my $declaration_name = shift; my $type; my $param; @@ -1254,7 +1255,7 @@ sub create_parameterlist($$$) { $type = $arg; $type =~ s/([^\(]+\(\*?)\s*$param/$1/; save_struct_actual($param); - push_parameter($param, $type, $file); + push_parameter($param, $type, $file, $declaration_name); } elsif ($arg) { $arg =~ s/\s*:\s*/:/g; $arg =~ s/\s*\[/\[/g; @@ -1279,27 +1280,28 @@ sub create_parameterlist($$$) { foreach $param (@args) { if ($param =~ m/^(\*+)\s*(.*)/) { save_struct_actual($2); - push_parameter($2, "$type $1", $file); + push_parameter($2, "$type $1", $file, $declaration_name); } elsif ($param =~ m/(.*?):(\d+)/) { if ($type ne "") { # skip unnamed bit-fields save_struct_actual($1); - push_parameter($1, "$type:$2", $file) + push_parameter($1, "$type:$2", $file, $declaration_name) } } else { save_struct_actual($param); - push_parameter($param, $type, $file); + push_parameter($param, $type, $file, $declaration_name); } } } } } -sub push_parameter($$$) { +sub push_parameter($$$$) { my $param = shift; my $type = shift; my $file = shift; + my $declaration_name = shift; if (($anon_struct_union == 1) && ($type eq "") && ($param eq "}")) { @@ -1336,21 +1338,13 @@ sub push_parameter($$$) { # warn if parameter has no description # (but ignore ones starting with # as these are not parameters # but inline preprocessor statements); - # also ignore unnamed structs/unions; - if (!$anon_struct_union) { + # Note: It will also ignore void params and unnamed structs/unions if (!defined $parameterdescs{$param} && $param !~ /^#/) { + $parameterdescs{$param} = $undescribed; - $parameterdescs{$param} = $undescribed; - - if (($type eq 'function') || ($type eq 'enum')) { - print STDERR "${file}:$.: warning: Function parameter ". - "or member '$param' not " . - "described in '$declaration_name'\n"; - } - print STDERR "${file}:$.: warning:" . - " No description found for parameter '$param'\n"; - ++$warnings; - } + print STDERR + "${file}:$.: warning: Function parameter or member '$param' not described in '$declaration_name'\n"; + ++$warnings; } $param = xml_escape($param); @@ -1507,7 +1501,7 @@ sub dump_function($$) { $declaration_name = $2; my $args = $3; - create_parameterlist($args, ',', $file); + create_parameterlist($args, ',', $file, $declaration_name); } else { print STDERR "${file}:$.: warning: cannot understand function prototype: '$prototype'\n"; return; -- cgit v1.2.3-59-g8ed1b From 7c0d7e87a16fe615e7913a3d56ce7bd26104ef0b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 18 Dec 2017 10:30:16 -0200 Subject: scripts: kernel-doc: handle nested struct function arguments Function arguments are different than usual ones. So, an special logic is needed in order to handle such arguments on nested structs. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index c97b89f47795..5d03c9086323 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1041,18 +1041,32 @@ sub dump_struct($$) { $id =~ s/^\*+//; foreach my $arg (split /;/, $content) { next if ($arg =~ m/^\s*$/); - my $type = $arg; - my $name = $arg; - $type =~ s/\s\S+$//; - $name =~ s/.*\s//; - $name =~ s/[:\[].*//; - $name =~ s/^\*+//; - next if (($name =~ m/^\s*$/)); - if ($id =~ m/^\s*$/) { - # anonymous struct/union - $newmember .= "$type $name;"; + if ($arg =~ m/^([^\(]+\(\*?\s*)([\w\.]*)(\s*\).*)/) { + # pointer-to-function + my $type = $1; + my $name = $2; + my $extra = $3; + next if (!$name); + if ($id =~ m/^\s*$/) { + # anonymous struct/union + $newmember .= "$type$name$extra;"; + } else { + $newmember .= "$type$id.$name$extra;"; + } } else { - $newmember .= "$type $id.$name;"; + my $type = $arg; + my $name = $arg; + $type =~ s/\s\S+$//; + $name =~ s/.*\s+//; + $name =~ s/[:\[].*//; + $name =~ s/^\*+//; + next if (($name =~ m/^\s*$/)); + if ($id =~ m/^\s*$/) { + # anonymous struct/union + $newmember .= "$type $name;"; + } else { + $newmember .= "$type $id.$name;"; + } } } $members =~ s/(struct|union)([^{};]+){([^{}]*)}([^{}\;]*)\;/$newmember/; @@ -1250,7 +1264,7 @@ sub create_parameterlist($$$$) { } elsif ($arg =~ m/\(.+\)\s*\(/) { # pointer-to-function $arg =~ tr/#/,/; - $arg =~ m/[^\(]+\(\*?\s*(\w*)\s*\)/; + $arg =~ m/[^\(]+\(\*?\s*([\w\.]*)\s*\)/; $param = $1; $type = $arg; $type =~ s/([^\(]+\(\*?)\s*$param/$1/; -- cgit v1.2.3-59-g8ed1b From 84ce5b987783d362ee4e737b653d6e2feacfa40c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 18 Dec 2017 10:30:17 -0200 Subject: scripts: kernel-doc: improve nested logic to handle multiple identifiers It is possible to use nested structs like: struct { struct { void *arg1; } st1, st2, *st3, st4; }; Handling it requires to split each parameter. Change the logic to allow such definitions. In order to test the new nested logic, the following file was used to test struct foo { int a; }; /* Just to avoid errors if compiled */ /** * struct my_struct - a struct with nested unions and structs * @arg1: first argument of anonymous union/anonymous struct * @arg2: second argument of anonymous union/anonymous struct * @arg1b: first argument of anonymous union/anonymous struct * @arg2b: second argument of anonymous union/anonymous struct * @arg3: third argument of anonymous union/anonymous struct * @arg4: fourth argument of anonymous union/anonymous struct * @bar.st1.arg1: first argument of struct st1 on union bar * @bar.st1.arg2: second argument of struct st1 on union bar * @bar.st1.bar1: bar1 at st1 * @bar.st1.bar2: bar2 at st1 * @bar.st2.arg1: first argument of struct st2 on union bar * @bar.st2.arg2: second argument of struct st2 on union bar * @bar.st3.arg2: second argument of struct st3 on union bar * @f1: nested function on anonimous union/struct * @bar.st2.f2: nested function on named union/struct */ struct my_struct { /* Anonymous union/struct*/ union { struct { char arg1 : 1; char arg2 : 3; }; struct { int arg1b; int arg2b; }; struct { void *arg3; int arg4; int (*f1)(char foo, int bar); }; }; union { struct { int arg1; int arg2; struct foo bar1, *bar2; } st1; /* bar.st1 is undocumented, cause a warning */ struct { void *arg1; /* bar.st3.arg1 is undocumented, cause a warning */ int arg2; int (*f2)(char foo, int bar); /* bar.st3.fn2 is undocumented, cause a warning */ } st2, st3, *st4; int (*f3)(char foo, int bar); /* f3 is undocumented, cause a warning */ } bar; /* bar is undocumented, cause a warning */ /* private: */ int undoc_privat; /* is undocumented but private, no warning */ /* public: */ int undoc_public; /* is undocumented, cause a warning */ }; It produces the following warnings, as expected: test2.h:57: warning: Function parameter or member 'bar' not described in 'my_struct' test2.h:57: warning: Function parameter or member 'bar.st1' not described in 'my_struct' test2.h:57: warning: Function parameter or member 'bar.st2' not described in 'my_struct' test2.h:57: warning: Function parameter or member 'bar.st3' not described in 'my_struct' test2.h:57: warning: Function parameter or member 'bar.st3.arg1' not described in 'my_struct' test2.h:57: warning: Function parameter or member 'bar.st3.f2' not described in 'my_struct' test2.h:57: warning: Function parameter or member 'bar.st4' not described in 'my_struct' test2.h:57: warning: Function parameter or member 'bar.st4.arg1' not described in 'my_struct' test2.h:57: warning: Function parameter or member 'bar.st4.arg2' not described in 'my_struct' test2.h:57: warning: Function parameter or member 'bar.st4.f2' not described in 'my_struct' test2.h:57: warning: Function parameter or member 'bar.f3' not described in 'my_struct' test2.h:57: warning: Function parameter or member 'undoc_public' not described in 'my_struct' Suggested-by: Markus Heiser Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 69 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 25 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 5d03c9086323..0bda21d9d3f2 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1030,15 +1030,16 @@ sub dump_struct($$) { my $declaration = $members; # Split nested struct/union elements as newer ones - my $cont = 1; - while ($cont) { - $cont = 0; - while ($members =~ m/(struct|union)([^{};]+){([^{}]*)}([^{}\;]*)\;/) { - my $newmember = "$1 $4;"; - my $id = $4; - my $content = $3; + while ($members =~ m/(struct|union)([^\{\};]+)\{([^\{\}]*)\}([^\{\}\;]*)\;/) { + my $newmember; + my $maintype = $1; + my $ids = $4; + my $content = $3; + foreach my $id(split /,/, $ids) { + $newmember .= "$maintype $id; "; + $id =~ s/[:\[].*//; - $id =~ s/^\*+//; + $id =~ s/^\s*\**(\S+)\s*/$1/; foreach my $arg (split /;/, $content) { next if ($arg =~ m/^\s*$/); if ($arg =~ m/^([^\(]+\(\*?\s*)([\w\.]*)(\s*\).*)/) { @@ -1049,30 +1050,48 @@ sub dump_struct($$) { next if (!$name); if ($id =~ m/^\s*$/) { # anonymous struct/union - $newmember .= "$type$name$extra;"; + $newmember .= "$type$name$extra; "; } else { - $newmember .= "$type$id.$name$extra;"; + $newmember .= "$type$id.$name$extra; "; } } else { - my $type = $arg; - my $name = $arg; - $type =~ s/\s\S+$//; - $name =~ s/.*\s+//; - $name =~ s/[:\[].*//; - $name =~ s/^\*+//; - next if (($name =~ m/^\s*$/)); - if ($id =~ m/^\s*$/) { - # anonymous struct/union - $newmember .= "$type $name;"; + my $type; + my $names; + $arg =~ s/^\s+//; + $arg =~ s/\s+$//; + # Handle bitmaps + $arg =~ s/:\s*\d+\s*//g; + # Handle arrays + $arg =~ s/\[\S+\]//g; + # The type may have multiple words, + # and multiple IDs can be defined, like: + # const struct foo, *bar, foobar + # So, we remove spaces when parsing the + # names, in order to match just names + # and commas for the names + $arg =~ s/\s*,\s*/,/g; + if ($arg =~ m/(.*)\s+([\S+,]+)/) { + $type = $1; + $names = $2; } else { - $newmember .= "$type $id.$name;"; + $newmember .= "$arg; "; + next; + } + foreach my $name (split /,/, $names) { + $name =~ s/^\s*\**(\S+)\s*/$1/; + next if (($name =~ m/^\s*$/)); + if ($id =~ m/^\s*$/) { + # anonymous struct/union + $newmember .= "$type $name; "; + } else { + $newmember .= "$type $id.$name; "; + } } } } - $members =~ s/(struct|union)([^{};]+){([^{}]*)}([^{}\;]*)\;/$newmember/; - $cont = 1; - }; - }; + } + $members =~ s/(struct|union)([^\{\};]+)\{([^\{\}]*)}([^\{\}\;]*)\;/$newmember/; + } # Ignore other nested elements, like enums $members =~ s/({[^\{\}]*})//g; -- cgit v1.2.3-59-g8ed1b From 2defb27292176959da02f1ba32940870dd1814eb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 18 Dec 2017 10:30:18 -0200 Subject: scripts: kernel-doc: apply filtering rules to warnings When kernel-doc is called with output selection filters, it will be called lots of time for a single file. If there is a warning present there, it means that it may print hundreds of identical warnings. Worse than that, the -function NAME actually filters only functions. So, it makes no sense at all to print warnings for structs or enums. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 0bda21d9d3f2..1e2b35ce1c9d 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1160,16 +1160,26 @@ sub dump_enum($$) { push @parameterlist, $arg; if (!$parameterdescs{$arg}) { $parameterdescs{$arg} = $undescribed; - print STDERR "${file}:$.: warning: Enum value '$arg' ". - "not described in enum '$declaration_name'\n"; + if (($output_selection == OUTPUT_ALL) || + ($output_selection == OUTPUT_INCLUDE && + defined($function_table{$declaration_name})) || + ($output_selection == OUTPUT_EXCLUDE && + !defined($function_table{$declaration_name}))) { + print STDERR "${file}:$.: warning: Enum value '$arg' not described in enum '$declaration_name'\n"; + } } $_members{$arg} = 1; } while (my ($k, $v) = each %parameterdescs) { if (!exists($_members{$k})) { - print STDERR "${file}:$.: warning: Excess enum value " . - "'$k' description in '$declaration_name'\n"; + if (($output_selection == OUTPUT_ALL) || + ($output_selection == OUTPUT_INCLUDE && + defined($function_table{$declaration_name})) || + ($output_selection == OUTPUT_EXCLUDE && + !defined($function_table{$declaration_name}))) { + print STDERR "${file}:$.: warning: Excess enum value '$k' description in '$declaration_name'\n"; + } } } @@ -1375,9 +1385,15 @@ sub push_parameter($$$$) { if (!defined $parameterdescs{$param} && $param !~ /^#/) { $parameterdescs{$param} = $undescribed; - print STDERR - "${file}:$.: warning: Function parameter or member '$param' not described in '$declaration_name'\n"; - ++$warnings; + if (($output_selection == OUTPUT_ALL) || + ($output_selection == OUTPUT_INCLUDE && + defined($function_table{$declaration_name})) || + ($output_selection == OUTPUT_EXCLUDE && + !defined($function_table{$declaration_name}))) { + print STDERR + "${file}:$.: warning: Function parameter or member '$param' not described in '$declaration_name'\n"; + ++$warnings; + } } $param = xml_escape($param); -- cgit v1.2.3-59-g8ed1b From 85afe608f5f3c10134e94c8aa87d9f9eecd81622 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 30 Dec 2017 22:32:55 -0200 Subject: scripts: kernel_doc: better handle show warnings logic The logic with inhibits warnings for definitions that is not output is incomplete: it doesn't cover the cases where OUTPUT_INTERNAL and OUTPUT_EXPORTED are used. As the most common case is OUTPUT_ALL, place it first, in order to optimize a litte bit the check logic. Fixes: 2defb2729217 ("scripts: kernel-doc: apply filtering rules to warnings") Reported-by: Randy Dunlap Acked-and-Tested-by: Randy Dunlap Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 56 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 15 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 1e2b35ce1c9d..fee8952037b1 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1140,6 +1140,44 @@ sub dump_struct($$) { } } + +sub show_warnings($$) { + my $functype = shift; + my $name = shift; + + return 1 if ($output_selection == OUTPUT_ALL); + + if ($output_selection == OUTPUT_EXPORTED) { + if (defined($function_table{$name})) { + return 1; + } else { + return 0; + } + } + if ($output_selection == OUTPUT_INTERNAL) { + if (!($functype eq "function" && defined($function_table{$name}))) { + return 1; + } else { + return 0; + } + } + if ($output_selection == OUTPUT_INCLUDE) { + if (defined($function_table{$name})) { + return 1; + } else { + return 0; + } + } + if ($output_selection == OUTPUT_EXCLUDE) { + if (!defined($function_table{$name})) { + return 1; + } else { + return 0; + } + } + die("Please add the new output type at show_warnings()"); +} + sub dump_enum($$) { my $x = shift; my $file = shift; @@ -1160,11 +1198,7 @@ sub dump_enum($$) { push @parameterlist, $arg; if (!$parameterdescs{$arg}) { $parameterdescs{$arg} = $undescribed; - if (($output_selection == OUTPUT_ALL) || - ($output_selection == OUTPUT_INCLUDE && - defined($function_table{$declaration_name})) || - ($output_selection == OUTPUT_EXCLUDE && - !defined($function_table{$declaration_name}))) { + if (show_warnings("enum", $declaration_name)) { print STDERR "${file}:$.: warning: Enum value '$arg' not described in enum '$declaration_name'\n"; } } @@ -1173,11 +1207,7 @@ sub dump_enum($$) { while (my ($k, $v) = each %parameterdescs) { if (!exists($_members{$k})) { - if (($output_selection == OUTPUT_ALL) || - ($output_selection == OUTPUT_INCLUDE && - defined($function_table{$declaration_name})) || - ($output_selection == OUTPUT_EXCLUDE && - !defined($function_table{$declaration_name}))) { + if (show_warnings("enum", $declaration_name)) { print STDERR "${file}:$.: warning: Excess enum value '$k' description in '$declaration_name'\n"; } } @@ -1385,11 +1415,7 @@ sub push_parameter($$$$) { if (!defined $parameterdescs{$param} && $param !~ /^#/) { $parameterdescs{$param} = $undescribed; - if (($output_selection == OUTPUT_ALL) || - ($output_selection == OUTPUT_INCLUDE && - defined($function_table{$declaration_name})) || - ($output_selection == OUTPUT_EXCLUDE && - !defined($function_table{$declaration_name}))) { + if (show_warnings($type, $declaration_name)) { print STDERR "${file}:$.: warning: Function parameter or member '$param' not described in '$declaration_name'\n"; ++$warnings; -- cgit v1.2.3-59-g8ed1b