These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / scripts / kernel-doc
index 9922e66..638a38e 100755 (executable)
@@ -133,6 +133,30 @@ use strict;
 #
 # All descriptions can be multiline, except the short function description.
 #
+# For really longs structs, you can also describe arguments inside the
+# body of the struct.
+# eg.
+# /**
+#  * struct my_struct - short description
+#  * @a: first member
+#  * @b: second member
+#  *
+#  * Longer description
+#  */
+# struct my_struct {
+#     int a;
+#     int b;
+#     /**
+#      * @c: This is longer description of C
+#      *
+#      * You can use paragraphs to describe arguments
+#      * using this method.
+#      */
+#     int c;
+# };
+#
+# This should be use only for struct/enum members.
+#
 # You can also add additional sections. When documenting kernel functions you
 # should document the "Context:" of the function, e.g. whether the functions
 # can be called form interrupts. Unlike other sections you can end it with an
@@ -182,59 +206,73 @@ my $type_env = '(\$\w+)';
 #  One for each output format
 
 # these work fairly well
-my %highlights_html = ( $type_constant, "<i>\$1</i>",
-                       $type_func, "<b>\$1</b>",
-                       $type_struct_xml, "<i>\$1</i>",
-                       $type_env, "<b><i>\$1</i></b>",
-                       $type_param, "<tt><b>\$1</b></tt>" );
+my @highlights_html = (
+                       [$type_constant, "<i>\$1</i>"],
+                       [$type_func, "<b>\$1</b>"],
+                       [$type_struct_xml, "<i>\$1</i>"],
+                       [$type_env, "<b><i>\$1</i></b>"],
+                       [$type_param, "<tt><b>\$1</b></tt>"]
+                      );
 my $local_lt = "\\\\\\\\lt:";
 my $local_gt = "\\\\\\\\gt:";
 my $blankline_html = $local_lt . "p" . $local_gt;      # was "<p>"
 
 # html version 5
-my %highlights_html5 = ( $type_constant, "<span class=\"const\">\$1</span>",
-                       $type_func, "<span class=\"func\">\$1</span>",
-                       $type_struct_xml, "<span class=\"struct\">\$1</span>",
-                       $type_env, "<span class=\"env\">\$1</span>",
-                       $type_param, "<span class=\"param\">\$1</span>" );
+my @highlights_html5 = (
+                        [$type_constant, "<span class=\"const\">\$1</span>"],
+                        [$type_func, "<span class=\"func\">\$1</span>"],
+                        [$type_struct_xml, "<span class=\"struct\">\$1</span>"],
+                        [$type_env, "<span class=\"env\">\$1</span>"],
+                        [$type_param, "<span class=\"param\">\$1</span>]"]
+                      );
 my $blankline_html5 = $local_lt . "br /" . $local_gt;
 
 # XML, docbook format
-my %highlights_xml = ( "([^=])\\\"([^\\\"<]+)\\\"", "\$1<quote>\$2</quote>",
-                       $type_constant, "<constant>\$1</constant>",
-                       $type_func, "<function>\$1</function>",
-                       $type_struct_xml, "<structname>\$1</structname>",
-                       $type_env, "<envar>\$1</envar>",
-                       $type_param, "<parameter>\$1</parameter>" );
+my @highlights_xml = (
+                      ["([^=])\\\"([^\\\"<]+)\\\"", "\$1<quote>\$2</quote>"],
+                      [$type_constant, "<constant>\$1</constant>"],
+                      [$type_struct_xml, "<structname>\$1</structname>"],
+                      [$type_param, "<parameter>\$1</parameter>"],
+                      [$type_func, "<function>\$1</function>"],
+                      [$type_env, "<envar>\$1</envar>"]
+                    );
 my $blankline_xml = $local_lt . "/para" . $local_gt . $local_lt . "para" . $local_gt . "\n";
 
 # gnome, docbook format
-my %highlights_gnome = ( $type_constant, "<replaceable class=\"option\">\$1</replaceable>",
-                        $type_func, "<function>\$1</function>",
-                        $type_struct, "<structname>\$1</structname>",
-                        $type_env, "<envar>\$1</envar>",
-                        $type_param, "<parameter>\$1</parameter>" );
+my @highlights_gnome = (
+                        [$type_constant, "<replaceable class=\"option\">\$1</replaceable>"],
+                        [$type_func, "<function>\$1</function>"],
+                        [$type_struct, "<structname>\$1</structname>"],
+                        [$type_env, "<envar>\$1</envar>"],
+                        [$type_param, "<parameter>\$1</parameter>" ]
+                      );
 my $blankline_gnome = "</para><para>\n";
 
 # these are pretty rough
-my %highlights_man = ( $type_constant, "\$1",
-                      $type_func, "\\\\fB\$1\\\\fP",
-                      $type_struct, "\\\\fI\$1\\\\fP",
-                      $type_param, "\\\\fI\$1\\\\fP" );
+my @highlights_man = (
+                      [$type_constant, "\$1"],
+                      [$type_func, "\\\\fB\$1\\\\fP"],
+                      [$type_struct, "\\\\fI\$1\\\\fP"],
+                      [$type_param, "\\\\fI\$1\\\\fP"]
+                    );
 my $blankline_man = "";
 
 # text-mode
-my %highlights_text = ( $type_constant, "\$1",
-                       $type_func, "\$1",
-                       $type_struct, "\$1",
-                       $type_param, "\$1" );
+my @highlights_text = (
+                       [$type_constant, "\$1"],
+                       [$type_func, "\$1"],
+                       [$type_struct, "\$1"],
+                       [$type_param, "\$1"]
+                     );
 my $blankline_text = "";
 
 # list mode
-my %highlights_list = ( $type_constant, "\$1",
-                       $type_func, "\$1",
-                       $type_struct, "\$1",
-                       $type_param, "\$1" );
+my @highlights_list = (
+                       [$type_constant, "\$1"],
+                       [$type_func, "\$1"],
+                       [$type_struct, "\$1"],
+                       [$type_param, "\$1"]
+                     );
 my $blankline_list = "";
 
 # read arguments
@@ -249,15 +287,24 @@ my $verbose = 0;
 my $output_mode = "man";
 my $output_preformatted = 0;
 my $no_doc_sections = 0;
-my %highlights = %highlights_man;
+my @highlights = @highlights_man;
 my $blankline = $blankline_man;
 my $modulename = "Kernel API";
 my $function_only = 0;
+my $show_not_found = 0;
+
+my @build_time;
+if (defined($ENV{'KBUILD_BUILD_TIMESTAMP'}) &&
+    (my $seconds = `date -d"${ENV{'KBUILD_BUILD_TIMESTAMP'}}" +%s`) ne '') {
+    @build_time = gmtime($seconds);
+} else {
+    @build_time = localtime;
+}
+
 my $man_date = ('January', 'February', 'March', 'April', 'May', 'June',
                'July', 'August', 'September', 'October',
-               'November', 'December')[(localtime)[4]] .
-  " " . ((localtime)[5]+1900);
-my $show_not_found = 0;
+               'November', 'December')[$build_time[4]] .
+  " " . ($build_time[5]+1900);
 
 # Essentially these are globals.
 # They probably want to be tidied up, made more localised or something.
@@ -287,9 +334,19 @@ my $lineprefix="";
 # 2 - scanning field start.
 # 3 - scanning prototype.
 # 4 - documentation block
+# 5 - gathering documentation outside main block
 my $state;
 my $in_doc_sect;
 
+# Split Doc State
+# 0 - Invalid (Before start or after finish)
+# 1 - Is started (the /** was found inside a struct)
+# 2 - The @parameter header was found, start accepting multi paragraph text.
+# 3 - Finished (the */ was found)
+# 4 - Error - Comment without header was found. Spit a warning as it's not
+#     proper kernel-doc and ignore the rest.
+my $split_doc_state;
+
 #declaration types: can be
 # 'function', 'struct', 'union', 'enum', 'typedef'
 my $decl_type;
@@ -304,6 +361,9 @@ my $doc_decl = $doc_com . '(\w+)';
 my $doc_sect = $doc_com . '([' . $doc_special . ']?[\w\s]+):(.*)';
 my $doc_content = $doc_com_body . '(.*)';
 my $doc_block = $doc_com . 'DOC:\s*(.*)?';
+my $doc_split_start = '^\s*/\*\*\s*$';
+my $doc_split_sect = '\s*\*\s*(@[\w\s]+):(.*)';
+my $doc_split_end = '^\s*\*/\s*$';
 
 my %constants;
 my %parameterdescs;
@@ -328,31 +388,31 @@ while ($ARGV[0] =~ m/^-(.*)/) {
     my $cmd = shift @ARGV;
     if ($cmd eq "-html") {
        $output_mode = "html";
-       %highlights = %highlights_html;
+       @highlights = @highlights_html;
        $blankline = $blankline_html;
     } elsif ($cmd eq "-html5") {
        $output_mode = "html5";
-       %highlights = %highlights_html5;
+       @highlights = @highlights_html5;
        $blankline = $blankline_html5;
     } elsif ($cmd eq "-man") {
        $output_mode = "man";
-       %highlights = %highlights_man;
+       @highlights = @highlights_man;
        $blankline = $blankline_man;
     } elsif ($cmd eq "-text") {
        $output_mode = "text";
-       %highlights = %highlights_text;
+       @highlights = @highlights_text;
        $blankline = $blankline_text;
     } elsif ($cmd eq "-docbook") {
        $output_mode = "xml";
-       %highlights = %highlights_xml;
+       @highlights = @highlights_xml;
        $blankline = $blankline_xml;
     } elsif ($cmd eq "-list") {
        $output_mode = "list";
-       %highlights = %highlights_list;
+       @highlights = @highlights_list;
        $blankline = $blankline_list;
     } elsif ($cmd eq "-gnome") {
        $output_mode = "gnome";
-       %highlights = %highlights_gnome;
+       @highlights = @highlights_gnome;
        $blankline = $blankline_gnome;
     } elsif ($cmd eq "-module") { # not needed for XML, inherits from calling document
        $modulename = shift @ARGV;
@@ -423,7 +483,7 @@ sub dump_section {
     } else {
 #      print STDERR "other section '$name' = '$contents'\n";
        if (defined($sections{$name}) && ($sections{$name} ne "")) {
-               print STDERR "Error(${file}:$.): duplicate section name '$name'\n";
+               print STDERR "${file}:$.: error: duplicate section name '$name'\n";
                ++$errors;
        }
        $sections{$name} = $contents;
@@ -1700,7 +1760,7 @@ sub output_declaration {
     my $func = "output_${functype}_$output_mode";
     if (($function_only==0) ||
        ( $function_only == 1 && defined($function_table{$name})) ||
-       ( $function_only == 2 && !defined($function_table{$name})))
+       ( $function_only == 2 && !($functype eq "function" && defined($function_table{$name}))))
     {
        &$func(@_);
        $section_counter++;
@@ -1745,15 +1805,17 @@ sub dump_struct($$) {
        $nested = $1;
 
        # ignore members marked private:
-       $members =~ s/\/\*\s*private:.*?\/\*\s*public:.*?\*\///gos;
-       $members =~ s/\/\*\s*private:.*//gos;
+       $members =~ s/\/\*\s*private:.*?\/\*\s*public:.*?\*\///gosi;
+       $members =~ s/\/\*\s*private:.*//gosi;
        # strip comments:
        $members =~ s/\/\*.*?\*\///gos;
        $nested =~ s/\/\*.*?\*\///gos;
        # strip kmemcheck_bitfield_{begin,end}.*;
        $members =~ s/kmemcheck_bitfield_.*?;//gos;
        # strip attributes
+       $members =~ s/__attribute__\s*\(\([a-z,_\*\s\(\)]*\)\)//i;
        $members =~ s/__aligned\s*\([^;]*\)//gos;
+       $members =~ s/\s*CRYPTO_MINALIGN_ATTR//gos;
 
        create_parameterlist($members, ';', $file);
        check_sections($file, $declaration_name, "struct", $sectcheck, $struct_actual, $nested);
@@ -1772,7 +1834,7 @@ sub dump_struct($$) {
                           });
     }
     else {
-       print STDERR "Error(${file}:$.): Cannot parse struct or union!\n";
+       print STDERR "${file}:$.: error: Cannot parse struct or union!\n";
        ++$errors;
     }
 }
@@ -1793,7 +1855,7 @@ sub dump_enum($$) {
            push @parameterlist, $arg;
            if (!$parameterdescs{$arg}) {
                $parameterdescs{$arg} = $undescribed;
-               print STDERR "Warning(${file}:$.): Enum value '$arg' ".
+               print STDERR "${file}:$.: warning: Enum value '$arg' ".
                    "not described in enum '$declaration_name'\n";
            }
 
@@ -1811,7 +1873,7 @@ sub dump_enum($$) {
                           });
     }
     else {
-       print STDERR "Error(${file}:$.): Cannot parse enum!\n";
+       print STDERR "${file}:$.: error: Cannot parse enum!\n";
        ++$errors;
     }
 }
@@ -1821,6 +1883,31 @@ sub dump_typedef($$) {
     my $file = shift;
 
     $x =~ s@/\*.*?\*/@@gos;    # strip comments.
+
+    # Parse function prototypes
+    if ($x =~ /typedef\s+(\w+)\s*\(\*\s*(\w\S+)\s*\)\s*\((.*)\);/) {
+       # Function typedefs
+       $return_type = $1;
+       $declaration_name = $2;
+       my $args = $3;
+
+       create_parameterlist($args, ',', $file);
+
+       output_declaration($declaration_name,
+                          'function',
+                          {'function' => $declaration_name,
+                           'module' => $modulename,
+                           'functiontype' => $return_type,
+                           'parameterlist' => \@parameterlist,
+                           'parameterdescs' => \%parameterdescs,
+                           'parametertypes' => \%parametertypes,
+                           'sectionlist' => \@sectionlist,
+                           'sections' => \%sections,
+                           'purpose' => $declaration_purpose
+                          });
+       return;
+    }
+
     while (($x =~ /\(*.\)\s*;$/) || ($x =~ /\[*.\]\s*;$/)) {
        $x =~ s/\(*.\)\s*;$/;/;
        $x =~ s/\[*.\]\s*;$/;/;
@@ -1839,7 +1926,7 @@ sub dump_typedef($$) {
                           });
     }
     else {
-       print STDERR "Error(${file}:$.): Cannot parse typedef!\n";
+       print STDERR "${file}:$.: error: Cannot parse typedef!\n";
        ++$errors;
     }
 }
@@ -1971,11 +2058,11 @@ sub push_parameter($$$) {
            $parameterdescs{$param_name} = $undescribed;
 
            if (($type eq 'function') || ($type eq 'enum')) {
-               print STDERR "Warning(${file}:$.): Function parameter ".
+               print STDERR "${file}:$.: warning: Function parameter ".
                    "or member '$param' not " .
                    "described in '$declaration_name'\n";
            }
-           print STDERR "Warning(${file}:$.):" .
+           print STDERR "${file}:$.: warning:" .
                         " No description found for parameter '$param'\n";
            ++$warnings;
        }
@@ -2026,14 +2113,14 @@ sub check_sections($$$$$$) {
                }
                if ($err) {
                        if ($decl_type eq "function") {
-                               print STDERR "Warning(${file}:$.): " .
+                               print STDERR "${file}:$.: warning: " .
                                        "Excess function parameter " .
                                        "'$sects[$sx]' " .
                                        "description in '$decl_name'\n";
                                ++$warnings;
                        } else {
                                if ($nested !~ m/\Q$sects[$sx]\E/) {
-                                   print STDERR "Warning(${file}:$.): " .
+                                   print STDERR "${file}:$.: warning: " .
                                        "Excess struct/union/enum/typedef member " .
                                        "'$sects[$sx]' " .
                                        "description in '$decl_name'\n";
@@ -2059,7 +2146,7 @@ sub check_return_section {
 
         if (!defined($sections{$section_return}) ||
             $sections{$section_return} eq "") {
-                print STDERR "Warning(${file}:$.): " .
+                print STDERR "${file}:$.: warning: " .
                         "No description found for return value of " .
                         "'$declaration_name'\n";
                 ++$warnings;
@@ -2138,7 +2225,7 @@ sub dump_function($$) {
 
        create_parameterlist($args, ',', $file);
     } else {
-       print STDERR "Warning(${file}:$.): cannot understand function prototype: '$prototype'\n";
+       print STDERR "${file}:$.: warning: cannot understand function prototype: '$prototype'\n";
        return;
     }
 
@@ -2181,6 +2268,7 @@ sub reset_state {
     $prototype = "";
 
     $state = 0;
+    $split_doc_state = 0;
 }
 
 sub tracepoint_munge($) {
@@ -2202,7 +2290,7 @@ sub tracepoint_munge($) {
                $tracepointargs = $1;
        }
        if (($tracepointname eq 0) || ($tracepointargs eq 0)) {
-               print STDERR "Warning(${file}:$.): Unrecognized tracepoint format: \n".
+               print STDERR "${file}:$.: warning: Unrecognized tracepoint format: \n".
                             "$prototype\n";
        } else {
                $prototype = "static inline void trace_$tracepointname($tracepointargs)";
@@ -2342,12 +2430,13 @@ sub process_file($) {
     my $descr;
     my $in_purpose = 0;
     my $initial_section_counter = $section_counter;
+    my ($orig_file) = @_;
 
     if (defined($ENV{'SRCTREE'})) {
-       $file = "$ENV{'SRCTREE'}" . "/" . "@_";
+       $file = "$ENV{'SRCTREE'}" . "/" . $orig_file;
     }
     else {
-       $file = "@_";
+       $file = $orig_file;
     }
     if (defined($source_map{$file})) {
        $file = $source_map{$file};
@@ -2401,7 +2490,7 @@ sub process_file($) {
                }
 
                if (($declaration_purpose eq "") && $verbose) {
-                       print STDERR "Warning(${file}:$.): missing initial short description on line:\n";
+                       print STDERR "${file}:$.: warning: missing initial short description on line:\n";
                        print STDERR $_;
                        ++$warnings;
                }
@@ -2419,10 +2508,10 @@ sub process_file($) {
                }
 
                if ($verbose) {
-                   print STDERR "Info(${file}:$.): Scanning doc for $identifier\n";
+                   print STDERR "${file}:$.: info: Scanning doc for $identifier\n";
                }
            } else {
-               print STDERR "Warning(${file}:$.): Cannot understand $_ on line $.",
+               print STDERR "${file}:$.: warning: Cannot understand $_ on line $.",
                " - I thought it was a doc line\n";
                ++$warnings;
                $state = 0;
@@ -2434,7 +2523,7 @@ sub process_file($) {
 
                if (($contents ne "") && ($contents ne "\n")) {
                    if (!$in_doc_sect && $verbose) {
-                       print STDERR "Warning(${file}:$.): contents before sections\n";
+                       print STDERR "${file}:$.: warning: contents before sections\n";
                        ++$warnings;
                    }
                    dump_section($file, $section, xml_escape($contents));
@@ -2453,7 +2542,6 @@ sub process_file($) {
                }
                $section = $newsection;
            } elsif (/$doc_end/) {
-
                if (($contents ne "") && ($contents ne "\n")) {
                    dump_section($file, $section, xml_escape($contents));
                    $section = $section_default;
@@ -2461,7 +2549,7 @@ sub process_file($) {
                }
                # look for doc_com + <text> + doc_end:
                if ($_ =~ m'\s*\*\s*[a-zA-Z_0-9:\.]+\*/') {
-                   print STDERR "Warning(${file}:$.): suspicious ending line: $_";
+                   print STDERR "${file}:$.: warning: suspicious ending line: $_";
                    ++$warnings;
                }
 
@@ -2491,11 +2579,47 @@ sub process_file($) {
                }
            } else {
                # i dont know - bad line?  ignore.
-               print STDERR "Warning(${file}:$.): bad line: $_";
+               print STDERR "${file}:$.: warning: bad line: $_";
                ++$warnings;
            }
+       } elsif ($state == 5) { # scanning for split parameters
+           # First line (state 1) needs to be a @parameter
+           if ($split_doc_state == 1 && /$doc_split_sect/o) {
+               $section = $1;
+               $contents = $2;
+               if ($contents ne "") {
+                   while ((substr($contents, 0, 1) eq " ") ||
+                          substr($contents, 0, 1) eq "\t") {
+                       $contents = substr($contents, 1);
+                   }
+               $contents .= "\n";
+               }
+               $split_doc_state = 2;
+           # Documentation block end */
+           } elsif (/$doc_split_end/) {
+               if (($contents ne "") && ($contents ne "\n")) {
+                   dump_section($file, $section, xml_escape($contents));
+                   $section = $section_default;
+                   $contents = "";
+               }
+               $state = 3;
+               $split_doc_state = 0;
+           # Regular text
+           } elsif (/$doc_content/) {
+               if ($split_doc_state == 2) {
+                   $contents .= $1 . "\n";
+               } elsif ($split_doc_state == 1) {
+                   $split_doc_state = 4;
+                   print STDERR "Warning(${file}:$.): ";
+                   print STDERR "Incorrect use of kernel-doc format: $_";
+                   ++$warnings;
+               }
+           }
        } elsif ($state == 3) { # scanning for function '{' (end of prototype)
-           if ($decl_type eq 'function') {
+           if (/$doc_split_start/) {
+               $state = 5;
+               $split_doc_state = 1;
+           } elsif ($decl_type eq 'function') {
                process_state3_function($_, $file);
            } else {
                process_state3_type($_, $file);
@@ -2547,7 +2671,7 @@ sub process_file($) {
        }
     }
     if ($initial_section_counter == $section_counter) {
-       print STDERR "Warning(${file}): no structured comments found\n";
+       print STDERR "${file}:1: warning: no structured comments found\n";
        if (($function_only == 1) && ($show_not_found == 1)) {
            print STDERR "    Was looking for '$_'.\n" for keys %function_table;
        }
@@ -2556,7 +2680,7 @@ sub process_file($) {
            print "<refentry>\n";
            print " <refnamediv>\n";
            print "  <refname>\n";
-           print "   ${file}\n";
+           print "   ${orig_file}\n";
            print "  </refname>\n";
            print "  <refpurpose>\n";
            print "   Document generation inconsistency\n";
@@ -2570,7 +2694,7 @@ sub process_file($) {
            print "   <para>\n";
            print "    The template for this document tried to insert\n";
            print "    the structured comment from the file\n";
-           print "    <filename>${file}</filename> at this point,\n";
+           print "    <filename>${orig_file}</filename> at this point,\n";
            print "    but none was found.\n";
            print "    This dummy section is inserted to allow\n";
            print "    generation to continue.\n";
@@ -2587,9 +2711,11 @@ $kernelversion = get_kernel_version();
 
 # generate a sequence of code that will splice in highlighting information
 # using the s// operator.
-foreach my $pattern (keys %highlights) {
-#   print STDERR "scanning pattern:$pattern, highlight:($highlights{$pattern})\n";
-    $dohighlight .=  "\$contents =~ s:$pattern:$highlights{$pattern}:gs;\n";
+for (my $k = 0; $k < @highlights; $k++) {
+    my $pattern = $highlights[$k][0];
+    my $result = $highlights[$k][1];
+#   print STDERR "scanning pattern:$pattern, highlight:($result)\n";
+    $dohighlight .=  "\$contents =~ s:$pattern:$result:gs;\n";
 }
 
 # Read the file that maps relative names to absolute names for