~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/scripts/kernel-doc

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /scripts/kernel-doc (Version linux-6.12-rc7) and /scripts/kernel-doc (Version linux-6.5.13)


  1 #!/usr/bin/env perl                                 1 #!/usr/bin/env perl
  2 # SPDX-License-Identifier: GPL-2.0                  2 # SPDX-License-Identifier: GPL-2.0
  3 # vim: softtabstop=4                           << 
  4                                                     3 
  5 use warnings;                                       4 use warnings;
  6 use strict;                                         5 use strict;
  7                                                     6 
  8 ## Copyright (c) 1998 Michael Zucchi, All Righ      7 ## Copyright (c) 1998 Michael Zucchi, All Rights Reserved        ##
  9 ## Copyright (C) 2000, 1  Tim Waugh <twaugh@red      8 ## Copyright (C) 2000, 1  Tim Waugh <twaugh@redhat.com>          ##
 10 ## Copyright (C) 2001  Simon Huggins                9 ## Copyright (C) 2001  Simon Huggins                             ##
 11 ## Copyright (C) 2005-2012  Randy Dunlap           10 ## Copyright (C) 2005-2012  Randy Dunlap                         ##
 12 ## Copyright (C) 2012  Dan Luedtke                 11 ## Copyright (C) 2012  Dan Luedtke                               ##
 13 ##                                                 12 ##                                                               ##
 14 ## #define enhancements by Armin Kuster <akuste     13 ## #define enhancements by Armin Kuster <akuster@mvista.com>     ##
 15 ## Copyright (c) 2000 MontaVista Software, Inc     14 ## Copyright (c) 2000 MontaVista Software, Inc.                  ##
 16 #                                                  15 #
 17 # Copyright (C) 2022 Tomasz Warniełło (POD)      16 # Copyright (C) 2022 Tomasz Warniełło (POD)
 18                                                    17 
 19 use Pod::Usage qw/pod2usage/;                      18 use Pod::Usage qw/pod2usage/;
 20                                                    19 
 21 =head1 NAME                                        20 =head1 NAME
 22                                                    21 
 23 kernel-doc - Print formatted kernel documentat     22 kernel-doc - Print formatted kernel documentation to stdout
 24                                                    23 
 25 =head1 SYNOPSIS                                    24 =head1 SYNOPSIS
 26                                                    25 
 27  kernel-doc [-h] [-v] [-Werror] [-Wall] [-Wret !!  26  kernel-doc [-h] [-v] [-Werror] [-Wall] [-Wreturn] [-Wshort-description] [-Wcontents-before-sections]
 28    [ -man |                                        27    [ -man |
 29      -rst [-sphinx-version VERSION] [-enable-l     28      -rst [-sphinx-version VERSION] [-enable-lineno] |
 30      -none                                         29      -none
 31    ]                                               30    ]
 32    [                                               31    [
 33      -export |                                     32      -export |
 34      -internal |                                   33      -internal |
 35      [-function NAME] ... |                        34      [-function NAME] ... |
 36      [-nosymbol NAME] ...                          35      [-nosymbol NAME] ...
 37    ]                                               36    ]
 38    [-no-doc-sections]                              37    [-no-doc-sections]
 39    [-export-file FILE] ...                         38    [-export-file FILE] ...
 40    FILE ...                                        39    FILE ...
 41                                                    40 
 42 Run `kernel-doc -h` for details.                   41 Run `kernel-doc -h` for details.
 43                                                    42 
 44 =head1 DESCRIPTION                                 43 =head1 DESCRIPTION
 45                                                    44 
 46 Read C language source or header FILEs, extrac     45 Read C language source or header FILEs, extract embedded documentation comments,
 47 and print formatted documentation to standard      46 and print formatted documentation to standard output.
 48                                                    47 
 49 The documentation comments are identified by t     48 The documentation comments are identified by the "/**" opening comment mark.
 50                                                    49 
 51 See Documentation/doc-guide/kernel-doc.rst for     50 See Documentation/doc-guide/kernel-doc.rst for the documentation comment syntax.
 52                                                    51 
 53 =cut                                               52 =cut
 54                                                    53 
 55 # more perldoc at the end of the file              54 # more perldoc at the end of the file
 56                                                    55 
 57 ## init lots of data                               56 ## init lots of data
 58                                                    57 
 59 my $errors = 0;                                    58 my $errors = 0;
 60 my $warnings = 0;                                  59 my $warnings = 0;
 61 my $anon_struct_union = 0;                         60 my $anon_struct_union = 0;
 62                                                    61 
 63 # match expressions used to find embedded type     62 # match expressions used to find embedded type information
 64 my $type_constant = '\b``([^\`]+)``\b';            63 my $type_constant = '\b``([^\`]+)``\b';
 65 my $type_constant2 = '\%([-_*\w]+)';           !!  64 my $type_constant2 = '\%([-_\w]+)';
 66 my $type_func = '(\w+)\(\)';                       65 my $type_func = '(\w+)\(\)';
 67 my $type_param = '\@(\w*((\.\w+)|(->\w+))*(\.\     66 my $type_param = '\@(\w*((\.\w+)|(->\w+))*(\.\.\.)?)';
 68 my $type_param_ref = '([\!~\*]?)\@(\w*((\.\w+) !!  67 my $type_param_ref = '([\!~]?)\@(\w*((\.\w+)|(->\w+))*(\.\.\.)?)';
 69 my $type_fp_param = '\@(\w+)\(\)';  # Special      68 my $type_fp_param = '\@(\w+)\(\)';  # Special RST handling for func ptr params
 70 my $type_fp_param2 = '\@(\w+->\S+)\(\)';  # Sp     69 my $type_fp_param2 = '\@(\w+->\S+)\(\)';  # Special RST handling for structs with func ptr params
 71 my $type_env = '(\$\w+)';                          70 my $type_env = '(\$\w+)';
 72 my $type_enum = '\&(enum\s*([_\w]+))';             71 my $type_enum = '\&(enum\s*([_\w]+))';
 73 my $type_struct = '\&(struct\s*([_\w]+))';         72 my $type_struct = '\&(struct\s*([_\w]+))';
 74 my $type_typedef = '\&(typedef\s*([_\w]+))';       73 my $type_typedef = '\&(typedef\s*([_\w]+))';
 75 my $type_union = '\&(union\s*([_\w]+))';           74 my $type_union = '\&(union\s*([_\w]+))';
 76 my $type_member = '\&([_\w]+)(\.|->)([_\w]+)';     75 my $type_member = '\&([_\w]+)(\.|->)([_\w]+)';
 77 my $type_fallback = '\&([_\w]+)';                  76 my $type_fallback = '\&([_\w]+)';
 78 my $type_member_func = $type_member . '\(\)';      77 my $type_member_func = $type_member . '\(\)';
 79                                                    78 
 80 # Output conversion substitutions.                 79 # Output conversion substitutions.
 81 #  One for each output format                      80 #  One for each output format
 82                                                    81 
 83 # these are pretty rough                           82 # these are pretty rough
 84 my @highlights_man = (                             83 my @highlights_man = (
 85     [$type_constant, "\$1"],                   !!  84                       [$type_constant, "\$1"],
 86     [$type_constant2, "\$1"],                  !!  85                       [$type_constant2, "\$1"],
 87     [$type_func, "\\\\fB\$1\\\\fP"],           !!  86                       [$type_func, "\\\\fB\$1\\\\fP"],
 88     [$type_enum, "\\\\fI\$1\\\\fP"],           !!  87                       [$type_enum, "\\\\fI\$1\\\\fP"],
 89     [$type_struct, "\\\\fI\$1\\\\fP"],         !!  88                       [$type_struct, "\\\\fI\$1\\\\fP"],
 90     [$type_typedef, "\\\\fI\$1\\\\fP"],        !!  89                       [$type_typedef, "\\\\fI\$1\\\\fP"],
 91     [$type_union, "\\\\fI\$1\\\\fP"],          !!  90                       [$type_union, "\\\\fI\$1\\\\fP"],
 92     [$type_param, "\\\\fI\$1\\\\fP"],          !!  91                       [$type_param, "\\\\fI\$1\\\\fP"],
 93     [$type_param_ref, "\\\\fI\$1\$2\\\\fP"],   !!  92                       [$type_param_ref, "\\\\fI\$1\$2\\\\fP"],
 94     [$type_member, "\\\\fI\$1\$2\$3\\\\fP"],   !!  93                       [$type_member, "\\\\fI\$1\$2\$3\\\\fP"],
 95     [$type_fallback, "\\\\fI\$1\\\\fP"]        !!  94                       [$type_fallback, "\\\\fI\$1\\\\fP"]
 96   );                                           !!  95                      );
 97 my $blankline_man = "";                            96 my $blankline_man = "";
 98                                                    97 
 99 # rst-mode                                         98 # rst-mode
100 my @highlights_rst = (                             99 my @highlights_rst = (
101     [$type_constant, "``\$1``"],               !! 100                        [$type_constant, "``\$1``"],
102     [$type_constant2, "``\$1``"],              !! 101                        [$type_constant2, "``\$1``"],
103                                                !! 102                        # Note: need to escape () to avoid func matching later
104     # Note: need to escape () to avoid func ma !! 103                        [$type_member_func, "\\:c\\:type\\:`\$1\$2\$3\\\\(\\\\) <\$1>`"],
105     [$type_member_func, "\\:c\\:type\\:`\$1\$2 !! 104                        [$type_member, "\\:c\\:type\\:`\$1\$2\$3 <\$1>`"],
106     [$type_member, "\\:c\\:type\\:`\$1\$2\$3 < !! 105                        [$type_fp_param, "**\$1\\\\(\\\\)**"],
107     [$type_fp_param, "**\$1\\\\(\\\\)**"],     !! 106                        [$type_fp_param2, "**\$1\\\\(\\\\)**"],
108     [$type_fp_param2, "**\$1\\\\(\\\\)**"],    !! 107                        [$type_func, "\$1()"],
109     [$type_func, "\$1()"],                     !! 108                        [$type_enum, "\\:c\\:type\\:`\$1 <\$2>`"],
110     [$type_enum, "\\:c\\:type\\:`\$1 <\$2>`"], !! 109                        [$type_struct, "\\:c\\:type\\:`\$1 <\$2>`"],
111     [$type_struct, "\\:c\\:type\\:`\$1 <\$2>`" !! 110                        [$type_typedef, "\\:c\\:type\\:`\$1 <\$2>`"],
112     [$type_typedef, "\\:c\\:type\\:`\$1 <\$2>` !! 111                        [$type_union, "\\:c\\:type\\:`\$1 <\$2>`"],
113     [$type_union, "\\:c\\:type\\:`\$1 <\$2>`"] !! 112                        # in rst this can refer to any type
114                                                !! 113                        [$type_fallback, "\\:c\\:type\\:`\$1`"],
115     # in rst this can refer to any type        !! 114                        [$type_param_ref, "**\$1\$2**"]
116     [$type_fallback, "\\:c\\:type\\:`\$1`"],   !! 115                       );
117     [$type_param_ref, "**\$1\$2**"]            << 
118   );                                           << 
119 my $blankline_rst = "\n";                         116 my $blankline_rst = "\n";
120                                                   117 
121 # read arguments                                  118 # read arguments
122 if ($#ARGV == -1) {                               119 if ($#ARGV == -1) {
123     pod2usage(                                 !! 120         pod2usage(
124         -message => "No arguments!\n",         !! 121                 -message => "No arguments!\n",
125         -exitval => 1,                         !! 122                 -exitval => 1,
126         -verbose => 99,                        !! 123                 -verbose => 99,
127         -sections => 'SYNOPSIS',               !! 124                 -sections => 'SYNOPSIS',
128         -output => \*STDERR,                   !! 125                 -output => \*STDERR,
129       );                                       !! 126         );
130 }                                                 127 }
131                                                   128 
132 my $kernelversion;                                129 my $kernelversion;
133 my ($sphinx_major, $sphinx_minor, $sphinx_patc    130 my ($sphinx_major, $sphinx_minor, $sphinx_patch);
134                                                   131 
135 my $dohighlight = "";                             132 my $dohighlight = "";
136                                                   133 
137 my $verbose = 0;                                  134 my $verbose = 0;
138 my $Werror = 0;                                   135 my $Werror = 0;
139 my $Wreturn = 0;                                  136 my $Wreturn = 0;
140 my $Wshort_desc = 0;                              137 my $Wshort_desc = 0;
141 my $Wcontents_before_sections = 0;                138 my $Wcontents_before_sections = 0;
142 my $output_mode = "rst";                          139 my $output_mode = "rst";
143 my $output_preformatted = 0;                      140 my $output_preformatted = 0;
144 my $no_doc_sections = 0;                          141 my $no_doc_sections = 0;
145 my $enable_lineno = 0;                            142 my $enable_lineno = 0;
146 my @highlights = @highlights_rst;                 143 my @highlights = @highlights_rst;
147 my $blankline = $blankline_rst;                   144 my $blankline = $blankline_rst;
148 my $modulename = "Kernel API";                    145 my $modulename = "Kernel API";
149                                                   146 
150 use constant {                                    147 use constant {
151     OUTPUT_ALL          => 0, # output all sym    148     OUTPUT_ALL          => 0, # output all symbols and doc sections
152     OUTPUT_INCLUDE      => 1, # output only sp    149     OUTPUT_INCLUDE      => 1, # output only specified symbols
153     OUTPUT_EXPORTED     => 2, # output exporte    150     OUTPUT_EXPORTED     => 2, # output exported symbols
154     OUTPUT_INTERNAL     => 3, # output non-exp    151     OUTPUT_INTERNAL     => 3, # output non-exported symbols
155 };                                                152 };
156 my $output_selection = OUTPUT_ALL;                153 my $output_selection = OUTPUT_ALL;
157 my $show_not_found = 0; # No longer used          154 my $show_not_found = 0; # No longer used
158                                                   155 
159 my @export_file_list;                             156 my @export_file_list;
160                                                   157 
161 my @build_time;                                   158 my @build_time;
162 if (defined($ENV{'KBUILD_BUILD_TIMESTAMP'}) &&    159 if (defined($ENV{'KBUILD_BUILD_TIMESTAMP'}) &&
163     (my $seconds = `date -d"${ENV{'KBUILD_BUIL    160     (my $seconds = `date -d"${ENV{'KBUILD_BUILD_TIMESTAMP'}}" +%s`) ne '') {
164     @build_time = gmtime($seconds);               161     @build_time = gmtime($seconds);
165 } else {                                          162 } else {
166     @build_time = localtime;                      163     @build_time = localtime;
167 }                                                 164 }
168                                                   165 
169 my $man_date = ('January', 'February', 'March'    166 my $man_date = ('January', 'February', 'March', 'April', 'May', 'June',
170                 'July', 'August', 'September', !! 167                 'July', 'August', 'September', 'October',
171                 'November', 'December')[$build !! 168                 'November', 'December')[$build_time[4]] .
172     " " . ($build_time[5]+1900);               !! 169   " " . ($build_time[5]+1900);
173                                                   170 
174 # Essentially these are globals.                  171 # Essentially these are globals.
175 # They probably want to be tidied up, made mor    172 # They probably want to be tidied up, made more localised or something.
176 # CAVEAT EMPTOR!  Some of the others I localis    173 # CAVEAT EMPTOR!  Some of the others I localised may not want to be, which
177 # could cause "use of undefined value" or othe    174 # could cause "use of undefined value" or other bugs.
178 my ($function, %function_table, %parametertype    175 my ($function, %function_table, %parametertypes, $declaration_purpose);
179 my %nosymbol_table = ();                          176 my %nosymbol_table = ();
180 my $declaration_start_line;                       177 my $declaration_start_line;
181 my ($type, $declaration_name, $return_type);      178 my ($type, $declaration_name, $return_type);
182 my ($newsection, $newcontents, $prototype, $br    179 my ($newsection, $newcontents, $prototype, $brcount, %source_map);
183                                                   180 
184 if (defined($ENV{'KBUILD_VERBOSE'}) && $ENV{'K    181 if (defined($ENV{'KBUILD_VERBOSE'}) && $ENV{'KBUILD_VERBOSE'} =~ '1') {
185     $verbose = 1;                              !! 182         $verbose = 1;
186 }                                                 183 }
187                                                   184 
188 if (defined($ENV{'KCFLAGS'})) {                   185 if (defined($ENV{'KCFLAGS'})) {
189     my $kcflags = "$ENV{'KCFLAGS'}";           !! 186         my $kcflags = "$ENV{'KCFLAGS'}";
190                                                   187 
191     if ($kcflags =~ /(\s|^)-Werror(\s|$)/) {   !! 188         if ($kcflags =~ /Werror/) {
192         $Werror = 1;                           !! 189                 $Werror = 1;
193     }                                          !! 190         }
194 }                                                 191 }
195                                                   192 
196 # reading this variable is for backwards compa    193 # reading this variable is for backwards compat just in case
197 # someone was calling it with the variable fro    194 # someone was calling it with the variable from outside the
198 # kernel's build system                           195 # kernel's build system
199 if (defined($ENV{'KDOC_WERROR'})) {               196 if (defined($ENV{'KDOC_WERROR'})) {
200     $Werror = "$ENV{'KDOC_WERROR'}";           !! 197         $Werror = "$ENV{'KDOC_WERROR'}";
201 }                                                 198 }
202 # other environment variables are converted to    199 # other environment variables are converted to command-line
203 # arguments in cmd_checkdoc in the build syste    200 # arguments in cmd_checkdoc in the build system
204                                                   201 
205 # Generated docbook code is inserted in a temp    202 # Generated docbook code is inserted in a template at a point where
206 # docbook v3.1 requires a non-zero sequence of    203 # docbook v3.1 requires a non-zero sequence of RefEntry's; see:
207 # https://www.oasis-open.org/docbook/documenta    204 # https://www.oasis-open.org/docbook/documentation/reference/html/refentry.html
208 # We keep track of number of generated entries    205 # We keep track of number of generated entries and generate a dummy
209 # if needs be to ensure the expanded template     206 # if needs be to ensure the expanded template can be postprocessed
210 # into html.                                      207 # into html.
211 my $section_counter = 0;                          208 my $section_counter = 0;
212                                                   209 
213 my $lineprefix="";                                210 my $lineprefix="";
214                                                   211 
215 # Parser states                                   212 # Parser states
216 use constant {                                    213 use constant {
217     STATE_NORMAL        => 0,        # normal     214     STATE_NORMAL        => 0,        # normal code
218     STATE_NAME          => 1,        # looking    215     STATE_NAME          => 1,        # looking for function name
219     STATE_BODY_MAYBE    => 2,        # body -     216     STATE_BODY_MAYBE    => 2,        # body - or maybe more description
220     STATE_BODY          => 3,        # the bod    217     STATE_BODY          => 3,        # the body of the comment
221     STATE_BODY_WITH_BLANK_LINE => 4, # the bod    218     STATE_BODY_WITH_BLANK_LINE => 4, # the body, which has a blank line
222     STATE_PROTO         => 5,        # scannin    219     STATE_PROTO         => 5,        # scanning prototype
223     STATE_DOCBLOCK      => 6,        # documen    220     STATE_DOCBLOCK      => 6,        # documentation block
224     STATE_INLINE        => 7,        # gatheri    221     STATE_INLINE        => 7,        # gathering doc outside main block
225 };                                                222 };
226 my $state;                                        223 my $state;
227 my $in_doc_sect;                                  224 my $in_doc_sect;
228 my $leading_space;                                225 my $leading_space;
229                                                   226 
230 # Inline documentation state                      227 # Inline documentation state
231 use constant {                                    228 use constant {
232     STATE_INLINE_NA     => 0, # not applicable    229     STATE_INLINE_NA     => 0, # not applicable ($state != STATE_INLINE)
233     STATE_INLINE_NAME   => 1, # looking for me    230     STATE_INLINE_NAME   => 1, # looking for member name (@foo:)
234     STATE_INLINE_TEXT   => 2, # looking for me    231     STATE_INLINE_TEXT   => 2, # looking for member documentation
235     STATE_INLINE_END    => 3, # done              232     STATE_INLINE_END    => 3, # done
236     STATE_INLINE_ERROR  => 4, # error - Commen    233     STATE_INLINE_ERROR  => 4, # error - Comment without header was found.
237                               # Spit a warning    234                               # Spit a warning as it's not
238                               # proper kernel-    235                               # proper kernel-doc and ignore the rest.
239 };                                                236 };
240 my $inline_doc_state;                             237 my $inline_doc_state;
241                                                   238 
242 #declaration types: can be                        239 #declaration types: can be
243 # 'function', 'struct', 'union', 'enum', 'type    240 # 'function', 'struct', 'union', 'enum', 'typedef'
244 my $decl_type;                                    241 my $decl_type;
245                                                   242 
246 # Name of the kernel-doc identifier for non-DO    243 # Name of the kernel-doc identifier for non-DOC markups
247 my $identifier;                                   244 my $identifier;
248                                                   245 
249 my $doc_start = '^/\*\*\s*$'; # Allow whitespa    246 my $doc_start = '^/\*\*\s*$'; # Allow whitespace at end of comment start.
250 my $doc_end = '\*/';                              247 my $doc_end = '\*/';
251 my $doc_com = '\s*\*\s*';                         248 my $doc_com = '\s*\*\s*';
252 my $doc_com_body = '\s*\* ?';                     249 my $doc_com_body = '\s*\* ?';
253 my $doc_decl = $doc_com . '(\w+)';                250 my $doc_decl = $doc_com . '(\w+)';
254 # @params and a strictly limited set of suppor    251 # @params and a strictly limited set of supported section names
255 # Specifically:                                   252 # Specifically:
256 #   Match @word:                                  253 #   Match @word:
257 #         @...:                                   254 #         @...:
258 #         @{section-name}:                        255 #         @{section-name}:
259 # while trying to not match literal block star    256 # while trying to not match literal block starts like "example::"
260 #                                                 257 #
261 my $doc_sect = $doc_com .                         258 my $doc_sect = $doc_com .
262     '\s*(\@[.\w]+|\@\.\.\.|description|context    259     '\s*(\@[.\w]+|\@\.\.\.|description|context|returns?|notes?|examples?)\s*:([^:].*)?$';
263 my $doc_content = $doc_com_body . '(.*)';         260 my $doc_content = $doc_com_body . '(.*)';
264 my $doc_block = $doc_com . 'DOC:\s*(.*)?';        261 my $doc_block = $doc_com . 'DOC:\s*(.*)?';
265 my $doc_inline_start = '^\s*/\*\*\s*$';           262 my $doc_inline_start = '^\s*/\*\*\s*$';
266 my $doc_inline_sect = '\s*\*\s*(@\s*[\w][\w\.]    263 my $doc_inline_sect = '\s*\*\s*(@\s*[\w][\w\.]*\s*):(.*)';
267 my $doc_inline_end = '^\s*\*/\s*$';               264 my $doc_inline_end = '^\s*\*/\s*$';
268 my $doc_inline_oneline = '^\s*/\*\*\s*(@[\w\s]    265 my $doc_inline_oneline = '^\s*/\*\*\s*(@[\w\s]+):\s*(.*)\s*\*/\s*$';
269 my $export_symbol = '^\s*EXPORT_SYMBOL(_GPL)?\    266 my $export_symbol = '^\s*EXPORT_SYMBOL(_GPL)?\s*\(\s*(\w+)\s*\)\s*;';
270 my $export_symbol_ns = '^\s*EXPORT_SYMBOL_NS(_    267 my $export_symbol_ns = '^\s*EXPORT_SYMBOL_NS(_GPL)?\s*\(\s*(\w+)\s*,\s*\w+\)\s*;';
271 my $function_pointer = qr{([^\(]*\(\*)\s*\)\s*    268 my $function_pointer = qr{([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)};
272 my $attribute = qr{__attribute__\s*\(\([a-z0-9    269 my $attribute = qr{__attribute__\s*\(\([a-z0-9,_\*\s\(\)]*\)\)}i;
273                                                   270 
274 my %parameterdescs;                               271 my %parameterdescs;
275 my %parameterdesc_start_lines;                    272 my %parameterdesc_start_lines;
276 my @parameterlist;                                273 my @parameterlist;
277 my %sections;                                     274 my %sections;
278 my @sectionlist;                                  275 my @sectionlist;
279 my %section_start_lines;                          276 my %section_start_lines;
280 my $sectcheck;                                    277 my $sectcheck;
281 my $struct_actual;                                278 my $struct_actual;
282                                                   279 
283 my $contents = "";                                280 my $contents = "";
284 my $new_start_line = 0;                           281 my $new_start_line = 0;
285                                                   282 
286 # the canonical section names. see also $doc_s    283 # the canonical section names. see also $doc_sect above.
287 my $section_default = "Description";    # defa    284 my $section_default = "Description";    # default section
288 my $section_intro = "Introduction";               285 my $section_intro = "Introduction";
289 my $section = $section_default;                   286 my $section = $section_default;
290 my $section_context = "Context";                  287 my $section_context = "Context";
291 my $section_return = "Return";                    288 my $section_return = "Return";
292                                                   289 
293 my $undescribed = "-- undescribed --";            290 my $undescribed = "-- undescribed --";
294                                                   291 
295 reset_state();                                    292 reset_state();
296                                                   293 
297 while ($ARGV[0] =~ m/^--?(.*)/) {                 294 while ($ARGV[0] =~ m/^--?(.*)/) {
298     my $cmd = $1;                                 295     my $cmd = $1;
299     shift @ARGV;                                  296     shift @ARGV;
300     if ($cmd eq "man") {                          297     if ($cmd eq "man") {
301         $output_mode = "man";                  !! 298         $output_mode = "man";
302         @highlights = @highlights_man;         !! 299         @highlights = @highlights_man;
303         $blankline = $blankline_man;           !! 300         $blankline = $blankline_man;
304     } elsif ($cmd eq "rst") {                     301     } elsif ($cmd eq "rst") {
305         $output_mode = "rst";                  !! 302         $output_mode = "rst";
306         @highlights = @highlights_rst;         !! 303         @highlights = @highlights_rst;
307         $blankline = $blankline_rst;           !! 304         $blankline = $blankline_rst;
308     } elsif ($cmd eq "none") {                    305     } elsif ($cmd eq "none") {
309         $output_mode = "none";                 !! 306         $output_mode = "none";
310     } elsif ($cmd eq "module") { # not needed     307     } elsif ($cmd eq "module") { # not needed for XML, inherits from calling document
311         $modulename = shift @ARGV;             !! 308         $modulename = shift @ARGV;
312     } elsif ($cmd eq "function") { # to only o    309     } elsif ($cmd eq "function") { # to only output specific functions
313         $output_selection = OUTPUT_INCLUDE;    !! 310         $output_selection = OUTPUT_INCLUDE;
314         $function = shift @ARGV;               !! 311         $function = shift @ARGV;
315         $function_table{$function} = 1;        !! 312         $function_table{$function} = 1;
316     } elsif ($cmd eq "nosymbol") { # Exclude s    313     } elsif ($cmd eq "nosymbol") { # Exclude specific symbols
317         my $symbol = shift @ARGV;              !! 314         my $symbol = shift @ARGV;
318         $nosymbol_table{$symbol} = 1;          !! 315         $nosymbol_table{$symbol} = 1;
319     } elsif ($cmd eq "export") { # only export    316     } elsif ($cmd eq "export") { # only exported symbols
320         $output_selection = OUTPUT_EXPORTED;   !! 317         $output_selection = OUTPUT_EXPORTED;
321         %function_table = ();                  !! 318         %function_table = ();
322     } elsif ($cmd eq "internal") { # only non-    319     } elsif ($cmd eq "internal") { # only non-exported symbols
323         $output_selection = OUTPUT_INTERNAL;   !! 320         $output_selection = OUTPUT_INTERNAL;
324         %function_table = ();                  !! 321         %function_table = ();
325     } elsif ($cmd eq "export-file") {             322     } elsif ($cmd eq "export-file") {
326         my $file = shift @ARGV;                !! 323         my $file = shift @ARGV;
327         push(@export_file_list, $file);        !! 324         push(@export_file_list, $file);
328     } elsif ($cmd eq "v") {                       325     } elsif ($cmd eq "v") {
329         $verbose = 1;                          !! 326         $verbose = 1;
330     } elsif ($cmd eq "Werror") {                  327     } elsif ($cmd eq "Werror") {
331         $Werror = 1;                           !! 328         $Werror = 1;
332     } elsif ($cmd eq "Wreturn") {                 329     } elsif ($cmd eq "Wreturn") {
333         $Wreturn = 1;                          !! 330         $Wreturn = 1;
334     } elsif ($cmd eq "Wshort-desc" or $cmd eq  !! 331     } elsif ($cmd eq "Wshort-desc") {
335         $Wshort_desc = 1;                      !! 332         $Wshort_desc = 1;
336     } elsif ($cmd eq "Wcontents-before-section    333     } elsif ($cmd eq "Wcontents-before-sections") {
337         $Wcontents_before_sections = 1;        !! 334         $Wcontents_before_sections = 1;
338     } elsif ($cmd eq "Wall") {                    335     } elsif ($cmd eq "Wall") {
339         $Wreturn = 1;                             336         $Wreturn = 1;
340         $Wshort_desc = 1;                         337         $Wshort_desc = 1;
341         $Wcontents_before_sections = 1;           338         $Wcontents_before_sections = 1;
342     } elsif (($cmd eq "h") || ($cmd eq "help")    339     } elsif (($cmd eq "h") || ($cmd eq "help")) {
343         pod2usage(-exitval => 0, -verbose => 2 !! 340                 pod2usage(-exitval => 0, -verbose => 2);
344     } elsif ($cmd eq 'no-doc-sections') {         341     } elsif ($cmd eq 'no-doc-sections') {
345         $no_doc_sections = 1;                  !! 342             $no_doc_sections = 1;
346     } elsif ($cmd eq 'enable-lineno') {           343     } elsif ($cmd eq 'enable-lineno') {
347         $enable_lineno = 1;                    !! 344             $enable_lineno = 1;
348     } elsif ($cmd eq 'show-not-found') {          345     } elsif ($cmd eq 'show-not-found') {
349         $show_not_found = 1;  # A no-op but do !! 346         $show_not_found = 1;  # A no-op but don't fail
350     } elsif ($cmd eq "sphinx-version") {          347     } elsif ($cmd eq "sphinx-version") {
351         my $ver_string = shift @ARGV;          !! 348         my $ver_string = shift @ARGV;
352         if ($ver_string =~ m/^(\d+)(\.\d+)?(\. !! 349         if ($ver_string =~ m/^(\d+)(\.\d+)?(\.\d+)?/) {
353             $sphinx_major = $1;                !! 350             $sphinx_major = $1;
354             if (defined($2)) {                 !! 351             if (defined($2)) {
355                 $sphinx_minor = substr($2,1);  !! 352                 $sphinx_minor = substr($2,1);
356             } else {                           !! 353             } else {
357                 $sphinx_minor = 0;             !! 354                 $sphinx_minor = 0;
358             }                                  !! 355             }
359             if (defined($3)) {                 !! 356             if (defined($3)) {
360                 $sphinx_patch = substr($3,1)   !! 357                 $sphinx_patch = substr($3,1)
361             } else {                           !! 358             } else {
362                 $sphinx_patch = 0;             !! 359                 $sphinx_patch = 0;
363             }                                  !! 360             }
364         } else {                               !! 361         } else {
365             die "Sphinx version should either  !! 362             die "Sphinx version should either major.minor or major.minor.patch format\n";
366         }                                      !! 363         }
367     } else {                                      364     } else {
368         # Unknown argument                     !! 365         # Unknown argument
369         pod2usage(                             !! 366         pod2usage(
370             -message => "Argument unknown!\n", !! 367             -message => "Argument unknown!\n",
371             -exitval => 1,                     !! 368             -exitval => 1,
372             -verbose => 99,                    !! 369             -verbose => 99,
373             -sections => 'SYNOPSIS',           !! 370             -sections => 'SYNOPSIS',
374             -output => \*STDERR,               !! 371             -output => \*STDERR,
375             );                                 !! 372             );
376     }                                             373     }
377     if ($#ARGV < 0){                              374     if ($#ARGV < 0){
378         pod2usage(                             !! 375         pod2usage(
379             -message => "FILE argument missing !! 376             -message => "FILE argument missing\n",
380             -exitval => 1,                     !! 377             -exitval => 1,
381             -verbose => 99,                    !! 378             -verbose => 99,
382             -sections => 'SYNOPSIS',           !! 379             -sections => 'SYNOPSIS',
383             -output => \*STDERR,               !! 380             -output => \*STDERR,
384             );                                 !! 381             );
385     }                                             382     }
386 }                                                 383 }
387                                                   384 
388 # continue execution near EOF;                    385 # continue execution near EOF;
389                                                   386 
390 # The C domain dialect changed on Sphinx 3. So    387 # The C domain dialect changed on Sphinx 3. So, we need to check the
391 # version in order to produce the right tags.     388 # version in order to produce the right tags.
392 sub findprog($)                                   389 sub findprog($)
393 {                                                 390 {
394     foreach(split(/:/, $ENV{PATH})) {          !! 391         foreach(split(/:/, $ENV{PATH})) {
395         return "$_/$_[0]" if(-x "$_/$_[0]");   !! 392                 return "$_/$_[0]" if(-x "$_/$_[0]");
396     }                                          !! 393         }
397 }                                                 394 }
398                                                   395 
399 sub get_sphinx_version()                          396 sub get_sphinx_version()
400 {                                                 397 {
401     my $ver;                                   !! 398         my $ver;
402                                                << 
403     my $cmd = "sphinx-build";                  << 
404     if (!findprog($cmd)) {                     << 
405         my $cmd = "sphinx-build3";             << 
406         if (!findprog($cmd)) {                 << 
407             $sphinx_major = 1;                 << 
408             $sphinx_minor = 2;                 << 
409             $sphinx_patch = 0;                 << 
410             printf STDERR "Warning: Sphinx ver << 
411                    $sphinx_major, $sphinx_mino << 
412             return;                            << 
413         }                                      << 
414     }                                          << 
415                                                   399 
416     open IN, "$cmd --version 2>&1 |";          !! 400         my $cmd = "sphinx-build";
417     while (<IN>) {                             !! 401         if (!findprog($cmd)) {
418         if (m/^\s*sphinx-build\s+([\d]+)\.([\d !! 402                 my $cmd = "sphinx-build3";
419             $sphinx_major = $1;                !! 403                 if (!findprog($cmd)) {
420             $sphinx_minor = $2;                !! 404                         $sphinx_major = 1;
421             $sphinx_patch = $3;                !! 405                         $sphinx_minor = 2;
422             last;                              !! 406                         $sphinx_patch = 0;
423         }                                      !! 407                         printf STDERR "Warning: Sphinx version not found. Using default (Sphinx version %d.%d.%d)\n",
424         # Sphinx 1.2.x uses a different format !! 408                                $sphinx_major, $sphinx_minor, $sphinx_patch;
425         if (m/^\s*Sphinx.*\s+([\d]+)\.([\d\.]+ !! 409                         return;
426             $sphinx_major = $1;                !! 410                 }
427             $sphinx_minor = $2;                !! 411         }
428             $sphinx_patch = $3;                !! 412 
429             last;                              !! 413         open IN, "$cmd --version 2>&1 |";
430         }                                      !! 414         while (<IN>) {
431     }                                          !! 415                 if (m/^\s*sphinx-build\s+([\d]+)\.([\d\.]+)(\+\/[\da-f]+)?$/) {
432     close IN;                                  !! 416                         $sphinx_major = $1;
                                                   >> 417                         $sphinx_minor = $2;
                                                   >> 418                         $sphinx_patch = $3;
                                                   >> 419                         last;
                                                   >> 420                 }
                                                   >> 421                 # Sphinx 1.2.x uses a different format
                                                   >> 422                 if (m/^\s*Sphinx.*\s+([\d]+)\.([\d\.]+)$/) {
                                                   >> 423                         $sphinx_major = $1;
                                                   >> 424                         $sphinx_minor = $2;
                                                   >> 425                         $sphinx_patch = $3;
                                                   >> 426                         last;
                                                   >> 427                 }
                                                   >> 428         }
                                                   >> 429         close IN;
433 }                                                 430 }
434                                                   431 
435 # get kernel version from env                     432 # get kernel version from env
436 sub get_kernel_version() {                        433 sub get_kernel_version() {
437     my $version = 'unknown kernel version';       434     my $version = 'unknown kernel version';
438                                                   435 
439     if (defined($ENV{'KERNELVERSION'})) {         436     if (defined($ENV{'KERNELVERSION'})) {
440         $version = $ENV{'KERNELVERSION'};      !! 437         $version = $ENV{'KERNELVERSION'};
441     }                                             438     }
442     return $version;                              439     return $version;
443 }                                                 440 }
444                                                   441 
445 #                                                 442 #
446 sub print_lineno {                                443 sub print_lineno {
447     my $lineno = shift;                           444     my $lineno = shift;
448     if ($enable_lineno && defined($lineno)) {     445     if ($enable_lineno && defined($lineno)) {
449         print ".. LINENO " . $lineno . "\n";      446         print ".. LINENO " . $lineno . "\n";
450     }                                             447     }
451 }                                                 448 }
452                                                   449 
453 sub emit_warning {                                450 sub emit_warning {
454     my $location = shift;                         451     my $location = shift;
455     my $msg = shift;                              452     my $msg = shift;
456     print STDERR "$location: warning: $msg";      453     print STDERR "$location: warning: $msg";
457     ++$warnings;                                  454     ++$warnings;
458 }                                                 455 }
459 ##                                                456 ##
460 # dumps section contents to arrays/hashes inte    457 # dumps section contents to arrays/hashes intended for that purpose.
461 #                                                 458 #
462 sub dump_section {                                459 sub dump_section {
463     my $file = shift;                             460     my $file = shift;
464     my $name = shift;                             461     my $name = shift;
465     my $contents = join "\n", @_;                 462     my $contents = join "\n", @_;
466                                                   463 
467     if ($name =~ m/$type_param/) {                464     if ($name =~ m/$type_param/) {
468         $name = $1;                            !! 465         $name = $1;
469         $parameterdescs{$name} = $contents;    !! 466         $parameterdescs{$name} = $contents;
470         $sectcheck = $sectcheck . $name . " "; !! 467         $sectcheck = $sectcheck . $name . " ";
471         $parameterdesc_start_lines{$name} = $n    468         $parameterdesc_start_lines{$name} = $new_start_line;
472         $new_start_line = 0;                      469         $new_start_line = 0;
473     } elsif ($name eq "@\.\.\.") {                470     } elsif ($name eq "@\.\.\.") {
474         $name = "...";                         !! 471         $name = "...";
475         $parameterdescs{$name} = $contents;    !! 472         $parameterdescs{$name} = $contents;
476         $sectcheck = $sectcheck . $name . " "; !! 473         $sectcheck = $sectcheck . $name . " ";
477         $parameterdesc_start_lines{$name} = $n    474         $parameterdesc_start_lines{$name} = $new_start_line;
478         $new_start_line = 0;                      475         $new_start_line = 0;
479     } else {                                      476     } else {
480         if (defined($sections{$name}) && ($sec !! 477         if (defined($sections{$name}) && ($sections{$name} ne "")) {
481             # Only warn on user specified dupl !! 478             # Only warn on user specified duplicate section names.
482             if ($name ne $section_default) {   !! 479             if ($name ne $section_default) {
483                 emit_warning("${file}:$.", "du !! 480                 emit_warning("${file}:$.", "duplicate section name '$name'\n");
484             }                                  !! 481             }
485             $sections{$name} .= $contents;     !! 482             $sections{$name} .= $contents;
486         } else {                               !! 483         } else {
487             $sections{$name} = $contents;      !! 484             $sections{$name} = $contents;
488             push @sectionlist, $name;          !! 485             push @sectionlist, $name;
489             $section_start_lines{$name} = $new    486             $section_start_lines{$name} = $new_start_line;
490             $new_start_line = 0;                  487             $new_start_line = 0;
491         }                                      !! 488         }
492     }                                             489     }
493 }                                                 490 }
494                                                   491 
495 ##                                                492 ##
496 # dump DOC: section after checking that it sho    493 # dump DOC: section after checking that it should go out
497 #                                                 494 #
498 sub dump_doc_section {                            495 sub dump_doc_section {
499     my $file = shift;                             496     my $file = shift;
500     my $name = shift;                             497     my $name = shift;
501     my $contents = join "\n", @_;                 498     my $contents = join "\n", @_;
502                                                   499 
503     if ($no_doc_sections) {                       500     if ($no_doc_sections) {
504         return;                                   501         return;
505     }                                             502     }
506                                                   503 
507     return if (defined($nosymbol_table{$name})    504     return if (defined($nosymbol_table{$name}));
508                                                   505 
509     if (($output_selection == OUTPUT_ALL) ||      506     if (($output_selection == OUTPUT_ALL) ||
510         (($output_selection == OUTPUT_INCLUDE) !! 507         (($output_selection == OUTPUT_INCLUDE) &&
511          defined($function_table{$name})))     !! 508          defined($function_table{$name})))
512     {                                             509     {
513         dump_section($file, $name, $contents); !! 510         dump_section($file, $name, $contents);
514         output_blockhead({'sectionlist' => \@s !! 511         output_blockhead({'sectionlist' => \@sectionlist,
515                           'sections' => \%sect !! 512                           'sections' => \%sections,
516                           'module' => $modulen !! 513                           'module' => $modulename,
517                           'content-only' => ($ !! 514                           'content-only' => ($output_selection != OUTPUT_ALL), });
518     }                                             515     }
519 }                                                 516 }
520                                                   517 
521 ##                                                518 ##
522 # output function                                 519 # output function
523 #                                                 520 #
524 # parameterdescs, a hash.                         521 # parameterdescs, a hash.
525 #  function => "function name"                    522 #  function => "function name"
526 #  parameterlist => @list of parameters           523 #  parameterlist => @list of parameters
527 #  parameterdescs => %parameter descriptions      524 #  parameterdescs => %parameter descriptions
528 #  sectionlist => @list of sections               525 #  sectionlist => @list of sections
529 #  sections => %section descriptions              526 #  sections => %section descriptions
530 #                                                 527 #
531                                                   528 
532 sub output_highlight {                            529 sub output_highlight {
533     my $contents = join "\n",@_;                  530     my $contents = join "\n",@_;
534     my $line;                                     531     my $line;
535                                                   532 
536 #   DEBUG                                         533 #   DEBUG
537 #   if (!defined $contents) {                     534 #   if (!defined $contents) {
538 #       use Carp;                                 535 #       use Carp;
539 #       confess "output_highlight got called w    536 #       confess "output_highlight got called with no args?\n";
540 #   }                                             537 #   }
541                                                   538 
542 #   print STDERR "contents b4:$contents\n";       539 #   print STDERR "contents b4:$contents\n";
543     eval $dohighlight;                            540     eval $dohighlight;
544     die $@ if $@;                                 541     die $@ if $@;
545 #   print STDERR "contents af:$contents\n";       542 #   print STDERR "contents af:$contents\n";
546                                                   543 
547     foreach $line (split "\n", $contents) {       544     foreach $line (split "\n", $contents) {
548         if (! $output_preformatted) {          !! 545         if (! $output_preformatted) {
549             $line =~ s/^\s*//;                 !! 546             $line =~ s/^\s*//;
550         }                                      !! 547         }
551         if ($line eq ""){                      !! 548         if ($line eq ""){
552             if (! $output_preformatted) {      !! 549             if (! $output_preformatted) {
553                 print $lineprefix, $blankline; !! 550                 print $lineprefix, $blankline;
554             }                                  !! 551             }
555         } else {                               !! 552         } else {
556             if ($output_mode eq "man" && subst !! 553             if ($output_mode eq "man" && substr($line, 0, 1) eq ".") {
557                 print "\\&$line";              !! 554                 print "\\&$line";
558             } else {                           !! 555             } else {
559                 print $lineprefix, $line;      !! 556                 print $lineprefix, $line;
560             }                                  !! 557             }
561         }                                      !! 558         }
562         print "\n";                            !! 559         print "\n";
563     }                                             560     }
564 }                                                 561 }
565                                                   562 
566 ##                                                563 ##
567 # output function in man                          564 # output function in man
568 sub output_function_man(%) {                      565 sub output_function_man(%) {
569     my %args = %{$_[0]};                          566     my %args = %{$_[0]};
570     my ($parameter, $section);                    567     my ($parameter, $section);
571     my $count;                                    568     my $count;
572                                                   569 
573     print ".TH \"$args{'function'}\" 9 \"$args    570     print ".TH \"$args{'function'}\" 9 \"$args{'function'}\" \"$man_date\" \"Kernel Hacker's Manual\" LINUX\n";
574                                                   571 
575     print ".SH NAME\n";                           572     print ".SH NAME\n";
576     print $args{'function'} . " \\- " . $args{    573     print $args{'function'} . " \\- " . $args{'purpose'} . "\n";
577                                                   574 
578     print ".SH SYNOPSIS\n";                       575     print ".SH SYNOPSIS\n";
579     if ($args{'functiontype'} ne "") {            576     if ($args{'functiontype'} ne "") {
580         print ".B \"" . $args{'functiontype'}  !! 577         print ".B \"" . $args{'functiontype'} . "\" " . $args{'function'} . "\n";
581     } else {                                      578     } else {
582         print ".B \"" . $args{'function'} . "\ !! 579         print ".B \"" . $args{'function'} . "\n";
583     }                                             580     }
584     $count = 0;                                   581     $count = 0;
585     my $parenth = "(";                            582     my $parenth = "(";
586     my $post = ",";                               583     my $post = ",";
587     foreach my $parameter (@{$args{'parameterl    584     foreach my $parameter (@{$args{'parameterlist'}}) {
588         if ($count == $#{$args{'parameterlist' !! 585         if ($count == $#{$args{'parameterlist'}}) {
589             $post = ");";                      !! 586             $post = ");";
590         }                                      !! 587         }
591         $type = $args{'parametertypes'}{$param !! 588         $type = $args{'parametertypes'}{$parameter};
592         if ($type =~ m/$function_pointer/) {   !! 589         if ($type =~ m/$function_pointer/) {
593             # pointer-to-function              !! 590             # pointer-to-function
594             print ".BI \"" . $parenth . $1 . " !! 591             print ".BI \"" . $parenth . $1 . "\" " . " \") (" . $2 . ")" . $post . "\"\n";
595         } else {                               !! 592         } else {
596             $type =~ s/([^\*])$/$1 /;          !! 593             $type =~ s/([^\*])$/$1 /;
597             print ".BI \"" . $parenth . $type  !! 594             print ".BI \"" . $parenth . $type . "\" " . " \"" . $post . "\"\n";
598         }                                      !! 595         }
599         $count++;                              !! 596         $count++;
600         $parenth = "";                         !! 597         $parenth = "";
601     }                                             598     }
602                                                   599 
603     print ".SH ARGUMENTS\n";                      600     print ".SH ARGUMENTS\n";
604     foreach $parameter (@{$args{'parameterlist    601     foreach $parameter (@{$args{'parameterlist'}}) {
605         my $parameter_name = $parameter;       !! 602         my $parameter_name = $parameter;
606         $parameter_name =~ s/\[.*//;           !! 603         $parameter_name =~ s/\[.*//;
607                                                   604 
608         print ".IP \"" . $parameter . "\" 12\n !! 605         print ".IP \"" . $parameter . "\" 12\n";
609         output_highlight($args{'parameterdescs !! 606         output_highlight($args{'parameterdescs'}{$parameter_name});
610     }                                             607     }
611     foreach $section (@{$args{'sectionlist'}})    608     foreach $section (@{$args{'sectionlist'}}) {
612         print ".SH \"", uc $section, "\"\n";   !! 609         print ".SH \"", uc $section, "\"\n";
613         output_highlight($args{'sections'}{$se !! 610         output_highlight($args{'sections'}{$section});
614     }                                             611     }
615 }                                                 612 }
616                                                   613 
617 ##                                                614 ##
618 # output enum in man                              615 # output enum in man
619 sub output_enum_man(%) {                          616 sub output_enum_man(%) {
620     my %args = %{$_[0]};                          617     my %args = %{$_[0]};
621     my ($parameter, $section);                    618     my ($parameter, $section);
622     my $count;                                    619     my $count;
623                                                   620 
624     print ".TH \"$args{'module'}\" 9 \"enum $a    621     print ".TH \"$args{'module'}\" 9 \"enum $args{'enum'}\" \"$man_date\" \"API Manual\" LINUX\n";
625                                                   622 
626     print ".SH NAME\n";                           623     print ".SH NAME\n";
627     print "enum " . $args{'enum'} . " \\- " .     624     print "enum " . $args{'enum'} . " \\- " . $args{'purpose'} . "\n";
628                                                   625 
629     print ".SH SYNOPSIS\n";                       626     print ".SH SYNOPSIS\n";
630     print "enum " . $args{'enum'} . " {\n";       627     print "enum " . $args{'enum'} . " {\n";
631     $count = 0;                                   628     $count = 0;
632     foreach my $parameter (@{$args{'parameterl    629     foreach my $parameter (@{$args{'parameterlist'}}) {
633         print ".br\n.BI \"    $parameter\"\n"; !! 630         print ".br\n.BI \"    $parameter\"\n";
634         if ($count == $#{$args{'parameterlist' !! 631         if ($count == $#{$args{'parameterlist'}}) {
635             print "\n};\n";                    !! 632             print "\n};\n";
636             last;                              !! 633             last;
637         } else {                               !! 634         }
638             print ", \n.br\n";                 !! 635         else {
639         }                                      !! 636             print ", \n.br\n";
640         $count++;                              !! 637         }
                                                   >> 638         $count++;
641     }                                             639     }
642                                                   640 
643     print ".SH Constants\n";                      641     print ".SH Constants\n";
644     foreach $parameter (@{$args{'parameterlist    642     foreach $parameter (@{$args{'parameterlist'}}) {
645         my $parameter_name = $parameter;       !! 643         my $parameter_name = $parameter;
646         $parameter_name =~ s/\[.*//;           !! 644         $parameter_name =~ s/\[.*//;
647                                                   645 
648         print ".IP \"" . $parameter . "\" 12\n !! 646         print ".IP \"" . $parameter . "\" 12\n";
649         output_highlight($args{'parameterdescs !! 647         output_highlight($args{'parameterdescs'}{$parameter_name});
650     }                                             648     }
651     foreach $section (@{$args{'sectionlist'}})    649     foreach $section (@{$args{'sectionlist'}}) {
652         print ".SH \"$section\"\n";            !! 650         print ".SH \"$section\"\n";
653         output_highlight($args{'sections'}{$se !! 651         output_highlight($args{'sections'}{$section});
654     }                                             652     }
655 }                                                 653 }
656                                                   654 
657 ##                                                655 ##
658 # output struct in man                            656 # output struct in man
659 sub output_struct_man(%) {                        657 sub output_struct_man(%) {
660     my %args = %{$_[0]};                          658     my %args = %{$_[0]};
661     my ($parameter, $section);                    659     my ($parameter, $section);
662                                                   660 
663     print ".TH \"$args{'module'}\" 9 \"" . $ar    661     print ".TH \"$args{'module'}\" 9 \"" . $args{'type'} . " " . $args{'struct'} . "\" \"$man_date\" \"API Manual\" LINUX\n";
664                                                   662 
665     print ".SH NAME\n";                           663     print ".SH NAME\n";
666     print $args{'type'} . " " . $args{'struct'    664     print $args{'type'} . " " . $args{'struct'} . " \\- " . $args{'purpose'} . "\n";
667                                                   665 
668     my $declaration = $args{'definition'};        666     my $declaration = $args{'definition'};
669     $declaration =~ s/\t/  /g;                    667     $declaration =~ s/\t/  /g;
670     $declaration =~ s/\n/"\n.br\n.BI \"/g;        668     $declaration =~ s/\n/"\n.br\n.BI \"/g;
671     print ".SH SYNOPSIS\n";                       669     print ".SH SYNOPSIS\n";
672     print $args{'type'} . " " . $args{'struct'    670     print $args{'type'} . " " . $args{'struct'} . " {\n.br\n";
673     print ".BI \"$declaration\n};\n.br\n\n";      671     print ".BI \"$declaration\n};\n.br\n\n";
674                                                   672 
675     print ".SH Members\n";                        673     print ".SH Members\n";
676     foreach $parameter (@{$args{'parameterlist    674     foreach $parameter (@{$args{'parameterlist'}}) {
677         ($parameter =~ /^#/) && next;          !! 675         ($parameter =~ /^#/) && next;
678                                                   676 
679         my $parameter_name = $parameter;       !! 677         my $parameter_name = $parameter;
680         $parameter_name =~ s/\[.*//;           !! 678         $parameter_name =~ s/\[.*//;
681                                                   679 
682         ($args{'parameterdescs'}{$parameter_na !! 680         ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
683         print ".IP \"" . $parameter . "\" 12\n !! 681         print ".IP \"" . $parameter . "\" 12\n";
684         output_highlight($args{'parameterdescs !! 682         output_highlight($args{'parameterdescs'}{$parameter_name});
685     }                                             683     }
686     foreach $section (@{$args{'sectionlist'}})    684     foreach $section (@{$args{'sectionlist'}}) {
687         print ".SH \"$section\"\n";            !! 685         print ".SH \"$section\"\n";
688         output_highlight($args{'sections'}{$se !! 686         output_highlight($args{'sections'}{$section});
689     }                                             687     }
690 }                                                 688 }
691                                                   689 
692 ##                                                690 ##
693 # output typedef in man                           691 # output typedef in man
694 sub output_typedef_man(%) {                       692 sub output_typedef_man(%) {
695     my %args = %{$_[0]};                          693     my %args = %{$_[0]};
696     my ($parameter, $section);                    694     my ($parameter, $section);
697                                                   695 
698     print ".TH \"$args{'module'}\" 9 \"$args{'    696     print ".TH \"$args{'module'}\" 9 \"$args{'typedef'}\" \"$man_date\" \"API Manual\" LINUX\n";
699                                                   697 
700     print ".SH NAME\n";                           698     print ".SH NAME\n";
701     print "typedef " . $args{'typedef'} . " \\    699     print "typedef " . $args{'typedef'} . " \\- " . $args{'purpose'} . "\n";
702                                                   700 
703     foreach $section (@{$args{'sectionlist'}})    701     foreach $section (@{$args{'sectionlist'}}) {
704         print ".SH \"$section\"\n";            !! 702         print ".SH \"$section\"\n";
705         output_highlight($args{'sections'}{$se !! 703         output_highlight($args{'sections'}{$section});
706     }                                             704     }
707 }                                                 705 }
708                                                   706 
709 sub output_blockhead_man(%) {                     707 sub output_blockhead_man(%) {
710     my %args = %{$_[0]};                          708     my %args = %{$_[0]};
711     my ($parameter, $section);                    709     my ($parameter, $section);
712     my $count;                                    710     my $count;
713                                                   711 
714     print ".TH \"$args{'module'}\" 9 \"$args{'    712     print ".TH \"$args{'module'}\" 9 \"$args{'module'}\" \"$man_date\" \"API Manual\" LINUX\n";
715                                                   713 
716     foreach $section (@{$args{'sectionlist'}})    714     foreach $section (@{$args{'sectionlist'}}) {
717         print ".SH \"$section\"\n";            !! 715         print ".SH \"$section\"\n";
718         output_highlight($args{'sections'}{$se !! 716         output_highlight($args{'sections'}{$section});
719     }                                             717     }
720 }                                                 718 }
721                                                   719 
722 ##                                                720 ##
723 # output in restructured text                     721 # output in restructured text
724 #                                                 722 #
725                                                   723 
726 #                                                 724 #
727 # This could use some work; it's used to outpu    725 # This could use some work; it's used to output the DOC: sections, and
728 # starts by putting out the name of the doc se    726 # starts by putting out the name of the doc section itself, but that tends
729 # to duplicate a header already in the templat    727 # to duplicate a header already in the template file.
730 #                                                 728 #
731 sub output_blockhead_rst(%) {                     729 sub output_blockhead_rst(%) {
732     my %args = %{$_[0]};                          730     my %args = %{$_[0]};
733     my ($parameter, $section);                    731     my ($parameter, $section);
734                                                   732 
735     foreach $section (@{$args{'sectionlist'}})    733     foreach $section (@{$args{'sectionlist'}}) {
736         next if (defined($nosymbol_table{$sect !! 734         next if (defined($nosymbol_table{$section}));
737                                                   735 
738         if ($output_selection != OUTPUT_INCLUD !! 736         if ($output_selection != OUTPUT_INCLUDE) {
739             print ".. _$section:\n\n";         !! 737             print ".. _$section:\n\n";
740             print "**$section**\n\n";          !! 738             print "**$section**\n\n";
741         }                                      !! 739         }
742         print_lineno($section_start_lines{$sec    740         print_lineno($section_start_lines{$section});
743         output_highlight_rst($args{'sections'} !! 741         output_highlight_rst($args{'sections'}{$section});
744         print "\n";                            !! 742         print "\n";
745     }                                             743     }
746 }                                                 744 }
747                                                   745 
748 #                                                 746 #
749 # Apply the RST highlights to a sub-block of t    747 # Apply the RST highlights to a sub-block of text.
750 #                                                 748 #
751 sub highlight_block($) {                          749 sub highlight_block($) {
752     # The dohighlight kludge requires the text    750     # The dohighlight kludge requires the text be called $contents
753     my $contents = shift;                         751     my $contents = shift;
754     eval $dohighlight;                            752     eval $dohighlight;
755     die $@ if $@;                                 753     die $@ if $@;
756     return $contents;                             754     return $contents;
757 }                                                 755 }
758                                                   756 
759 #                                                 757 #
760 # Regexes used only here.                         758 # Regexes used only here.
761 #                                                 759 #
762 my $sphinx_literal = '^[^.].*::$';                760 my $sphinx_literal = '^[^.].*::$';
763 my $sphinx_cblock = '^\.\.\ +code-block::';       761 my $sphinx_cblock = '^\.\.\ +code-block::';
764                                                   762 
765 sub output_highlight_rst {                        763 sub output_highlight_rst {
766     my $input = join "\n",@_;                     764     my $input = join "\n",@_;
767     my $output = "";                              765     my $output = "";
768     my $line;                                     766     my $line;
769     my $in_literal = 0;                           767     my $in_literal = 0;
770     my $litprefix;                                768     my $litprefix;
771     my $block = "";                               769     my $block = "";
772                                                   770 
773     foreach $line (split "\n",$input) {           771     foreach $line (split "\n",$input) {
774         #                                      !! 772         #
775         # If we're in a literal block, see if  !! 773         # If we're in a literal block, see if we should drop out
776         # of it.  Otherwise pass the line stra !! 774         # of it.  Otherwise pass the line straight through unmunged.
777         #                                      !! 775         #
778         if ($in_literal) {                     !! 776         if ($in_literal) {
779             if (! ($line =~ /^\s*$/)) {        !! 777             if (! ($line =~ /^\s*$/)) {
780                 #                              !! 778                 #
781                 # If this is the first non-bla !! 779                 # If this is the first non-blank line in a literal
782                 # block we need to figure out  !! 780                 # block we need to figure out what the proper indent is.
783                 #                              !! 781                 #
784                 if ($litprefix eq "") {        !! 782                 if ($litprefix eq "") {
785                     $line =~ /^(\s*)/;         !! 783                     $line =~ /^(\s*)/;
786                     $litprefix = '^' . $1;     !! 784                     $litprefix = '^' . $1;
787                     $output .= $line . "\n";   !! 785                     $output .= $line . "\n";
788                 } elsif (! ($line =~ /$litpref !! 786                 } elsif (! ($line =~ /$litprefix/)) {
789                     $in_literal = 0;           !! 787                     $in_literal = 0;
790                 } else {                       !! 788                 } else {
791                     $output .= $line . "\n";   !! 789                     $output .= $line . "\n";
792                 }                              !! 790                 }
793             } else {                           !! 791             } else {
794                 $output .= $line . "\n";       !! 792                 $output .= $line . "\n";
795             }                                  !! 793             }
796         }                                      !! 794         }
797         #                                      !! 795         #
798         # Not in a literal block (or just drop !! 796         # Not in a literal block (or just dropped out)
799         #                                      !! 797         #
800         if (! $in_literal) {                   !! 798         if (! $in_literal) {
801             $block .= $line . "\n";            !! 799             $block .= $line . "\n";
802             if (($line =~ /$sphinx_literal/) | !! 800             if (($line =~ /$sphinx_literal/) || ($line =~ /$sphinx_cblock/)) {
803                 $in_literal = 1;               !! 801                 $in_literal = 1;
804                 $litprefix = "";               !! 802                 $litprefix = "";
805                 $output .= highlight_block($bl !! 803                 $output .= highlight_block($block);
806                 $block = ""                    !! 804                 $block = ""
807             }                                  !! 805             }
808         }                                      !! 806         }
809     }                                             807     }
810                                                   808 
811     if ($block) {                                 809     if ($block) {
812         $output .= highlight_block($block);    !! 810         $output .= highlight_block($block);
813     }                                             811     }
814     foreach $line (split "\n", $output) {         812     foreach $line (split "\n", $output) {
815         print $lineprefix . $line . "\n";      !! 813         print $lineprefix . $line . "\n";
816     }                                             814     }
817 }                                                 815 }
818                                                   816 
819 sub output_function_rst(%) {                      817 sub output_function_rst(%) {
820     my %args = %{$_[0]};                          818     my %args = %{$_[0]};
821     my ($parameter, $section);                    819     my ($parameter, $section);
822     my $oldprefix = $lineprefix;                  820     my $oldprefix = $lineprefix;
                                                   >> 821     my $start = "";
                                                   >> 822     my $is_macro = 0;
823                                                   823 
824     my $signature = "";                        !! 824     if ($sphinx_major < 3) {
                                                   >> 825         if ($args{'typedef'}) {
                                                   >> 826             print ".. c:type:: ". $args{'function'} . "\n\n";
                                                   >> 827             print_lineno($declaration_start_line);
                                                   >> 828             print "   **Typedef**: ";
                                                   >> 829             $lineprefix = "";
                                                   >> 830             output_highlight_rst($args{'purpose'});
                                                   >> 831             $start = "\n\n**Syntax**\n\n  ``";
                                                   >> 832             $is_macro = 1;
                                                   >> 833         } else {
                                                   >> 834             print ".. c:function:: ";
                                                   >> 835         }
                                                   >> 836     } else {
                                                   >> 837         if ($args{'typedef'} || $args{'functiontype'} eq "") {
                                                   >> 838             $is_macro = 1;
                                                   >> 839             print ".. c:macro:: ". $args{'function'} . "\n\n";
                                                   >> 840         } else {
                                                   >> 841             print ".. c:function:: ";
                                                   >> 842         }
                                                   >> 843 
                                                   >> 844         if ($args{'typedef'}) {
                                                   >> 845             print_lineno($declaration_start_line);
                                                   >> 846             print "   **Typedef**: ";
                                                   >> 847             $lineprefix = "";
                                                   >> 848             output_highlight_rst($args{'purpose'});
                                                   >> 849             $start = "\n\n**Syntax**\n\n  ``";
                                                   >> 850         } else {
                                                   >> 851             print "``" if ($is_macro);
                                                   >> 852         }
                                                   >> 853     }
825     if ($args{'functiontype'} ne "") {            854     if ($args{'functiontype'} ne "") {
826         $signature = $args{'functiontype'} . " !! 855         $start .= $args{'functiontype'} . " " . $args{'function'} . " (";
827     } else {                                      856     } else {
828         $signature = $args{'function'} . " ("; !! 857         $start .= $args{'function'} . " (";
829     }                                             858     }
                                                   >> 859     print $start;
830                                                   860 
831     my $count = 0;                                861     my $count = 0;
832     foreach my $parameter (@{$args{'parameterl    862     foreach my $parameter (@{$args{'parameterlist'}}) {
833         if ($count ne 0) {                     !! 863         if ($count ne 0) {
834             $signature .= ", ";                !! 864             print ", ";
835         }                                      !! 865         }
836         $count++;                              !! 866         $count++;
837         $type = $args{'parametertypes'}{$param !! 867         $type = $args{'parametertypes'}{$parameter};
838                                                !! 868 
839         if ($type =~ m/$function_pointer/) {   !! 869         if ($type =~ m/$function_pointer/) {
840             # pointer-to-function              !! 870             # pointer-to-function
841             $signature .= $1 . $parameter . ") !! 871             print $1 . $parameter . ") (" . $2 . ")";
842         } else {                               !! 872         } else {
843             $signature .= $type;               !! 873             print $type;
844         }                                      !! 874         }
845     }                                             875     }
846                                                !! 876     if ($is_macro) {
847     $signature .= ")";                         !! 877         print ")``\n\n";
848                                                << 
849     if ($sphinx_major < 3) {                   << 
850         if ($args{'typedef'}) {                << 
851             print ".. c:type:: ". $args{'funct << 
852             print_lineno($declaration_start_li << 
853             print "   **Typedef**: ";          << 
854             $lineprefix = "";                  << 
855             output_highlight_rst($args{'purpos << 
856             print "\n\n**Syntax**\n\n";        << 
857             print "  ``$signature``\n\n";      << 
858         } else {                               << 
859             print ".. c:function:: $signature\ << 
860         }                                      << 
861     } else {                                      878     } else {
862         if ($args{'typedef'} || $args{'functio !! 879         print ")\n\n";
863             print ".. c:macro:: ". $args{'func << 
864                                                << 
865             if ($args{'typedef'}) {            << 
866                 print_lineno($declaration_star << 
867                 print "   **Typedef**: ";      << 
868                 $lineprefix = "";              << 
869                 output_highlight_rst($args{'pu << 
870                 print "\n\n**Syntax**\n\n";    << 
871                 print "  ``$signature``\n\n";  << 
872             } else {                           << 
873                 print "``$signature``\n\n";    << 
874             }                                  << 
875         } else {                               << 
876             print ".. c:function:: $signature\ << 
877         }                                      << 
878     }                                             880     }
879                                                << 
880     if (!$args{'typedef'}) {                      881     if (!$args{'typedef'}) {
881         print_lineno($declaration_start_line); !! 882         print_lineno($declaration_start_line);
882         $lineprefix = "   ";                   !! 883         $lineprefix = "   ";
883         output_highlight_rst($args{'purpose'}) !! 884         output_highlight_rst($args{'purpose'});
884         print "\n";                            !! 885         print "\n";
885     }                                             886     }
886                                                   887 
887     #                                             888     #
888     # Put our descriptive text into a containe    889     # Put our descriptive text into a container (thus an HTML <div>) to help
889     # set the function prototypes apart.          890     # set the function prototypes apart.
890     #                                             891     #
891     print ".. container:: kernelindent\n\n";      892     print ".. container:: kernelindent\n\n";
892     $lineprefix = "  ";                           893     $lineprefix = "  ";
893     print $lineprefix . "**Parameters**\n\n";     894     print $lineprefix . "**Parameters**\n\n";
894     foreach $parameter (@{$args{'parameterlist    895     foreach $parameter (@{$args{'parameterlist'}}) {
895         my $parameter_name = $parameter;       !! 896         my $parameter_name = $parameter;
896         $parameter_name =~ s/\[.*//;           !! 897         $parameter_name =~ s/\[.*//;
897         $type = $args{'parametertypes'}{$param !! 898         $type = $args{'parametertypes'}{$parameter};
898                                                !! 899 
899         if ($type ne "") {                     !! 900         if ($type ne "") {
900             print $lineprefix . "``$type``\n"; !! 901             print $lineprefix . "``$type``\n";
901         } else {                               !! 902         } else {
902             print $lineprefix . "``$parameter` !! 903             print $lineprefix . "``$parameter``\n";
903         }                                      !! 904         }
904                                                   905 
905         print_lineno($parameterdesc_start_line    906         print_lineno($parameterdesc_start_lines{$parameter_name});
906                                                   907 
907         $lineprefix = "    ";                  !! 908         $lineprefix = "    ";
908         if (defined($args{'parameterdescs'}{$p !! 909         if (defined($args{'parameterdescs'}{$parameter_name}) &&
909             $args{'parameterdescs'}{$parameter !! 910             $args{'parameterdescs'}{$parameter_name} ne $undescribed) {
910             output_highlight_rst($args{'parame !! 911             output_highlight_rst($args{'parameterdescs'}{$parameter_name});
911         } else {                               !! 912         } else {
912             print $lineprefix . "*undescribed* !! 913             print $lineprefix . "*undescribed*\n";
913         }                                      !! 914         }
914         $lineprefix = "  ";                    !! 915         $lineprefix = "  ";
915         print "\n";                            !! 916         print "\n";
916     }                                             917     }
917                                                   918 
918     output_section_rst(@_);                       919     output_section_rst(@_);
919     $lineprefix = $oldprefix;                     920     $lineprefix = $oldprefix;
920 }                                                 921 }
921                                                   922 
922 sub output_section_rst(%) {                       923 sub output_section_rst(%) {
923     my %args = %{$_[0]};                          924     my %args = %{$_[0]};
924     my $section;                                  925     my $section;
925     my $oldprefix = $lineprefix;                  926     my $oldprefix = $lineprefix;
926                                                   927 
927     foreach $section (@{$args{'sectionlist'}})    928     foreach $section (@{$args{'sectionlist'}}) {
928         print $lineprefix . "**$section**\n\n" !! 929         print $lineprefix . "**$section**\n\n";
929         print_lineno($section_start_lines{$sec    930         print_lineno($section_start_lines{$section});
930         output_highlight_rst($args{'sections'} !! 931         output_highlight_rst($args{'sections'}{$section});
931         print "\n";                            !! 932         print "\n";
932     }                                             933     }
933     print "\n";                                   934     print "\n";
934 }                                                 935 }
935                                                   936 
936 sub output_enum_rst(%) {                          937 sub output_enum_rst(%) {
937     my %args = %{$_[0]};                          938     my %args = %{$_[0]};
938     my ($parameter);                              939     my ($parameter);
939     my $oldprefix = $lineprefix;                  940     my $oldprefix = $lineprefix;
940     my $count;                                    941     my $count;
941     my $outer;                                    942     my $outer;
942                                                   943 
943     if ($sphinx_major < 3) {                      944     if ($sphinx_major < 3) {
944         my $name = "enum " . $args{'enum'};    !! 945         my $name = "enum " . $args{'enum'};
945         print "\n\n.. c:type:: " . $name . "\n !! 946         print "\n\n.. c:type:: " . $name . "\n\n";
946     } else {                                      947     } else {
947         my $name = $args{'enum'};              !! 948         my $name = $args{'enum'};
948         print "\n\n.. c:enum:: " . $name . "\n !! 949         print "\n\n.. c:enum:: " . $name . "\n\n";
949     }                                             950     }
950     print_lineno($declaration_start_line);        951     print_lineno($declaration_start_line);
951     $lineprefix = "  ";                           952     $lineprefix = "  ";
952     output_highlight_rst($args{'purpose'});       953     output_highlight_rst($args{'purpose'});
953     print "\n";                                   954     print "\n";
954                                                   955 
955     print ".. container:: kernelindent\n\n";      956     print ".. container:: kernelindent\n\n";
956     $outer = $lineprefix . "  ";                  957     $outer = $lineprefix . "  ";
957     $lineprefix = $outer . "  ";                  958     $lineprefix = $outer . "  ";
958     print $outer . "**Constants**\n\n";           959     print $outer . "**Constants**\n\n";
959     foreach $parameter (@{$args{'parameterlist    960     foreach $parameter (@{$args{'parameterlist'}}) {
960         print $outer . "``$parameter``\n";     !! 961         print $outer . "``$parameter``\n";
961                                                   962 
962         if ($args{'parameterdescs'}{$parameter !! 963         if ($args{'parameterdescs'}{$parameter} ne $undescribed) {
963             output_highlight_rst($args{'parame !! 964             output_highlight_rst($args{'parameterdescs'}{$parameter});
964         } else {                               !! 965         } else {
965             print $lineprefix . "*undescribed* !! 966             print $lineprefix . "*undescribed*\n";
966         }                                      !! 967         }
967         print "\n";                            !! 968         print "\n";
968     }                                             969     }
969     print "\n";                                   970     print "\n";
970     $lineprefix = $oldprefix;                     971     $lineprefix = $oldprefix;
971     output_section_rst(@_);                       972     output_section_rst(@_);
972 }                                                 973 }
973                                                   974 
974 sub output_typedef_rst(%) {                       975 sub output_typedef_rst(%) {
975     my %args = %{$_[0]};                          976     my %args = %{$_[0]};
976     my ($parameter);                              977     my ($parameter);
977     my $oldprefix = $lineprefix;                  978     my $oldprefix = $lineprefix;
978     my $name;                                     979     my $name;
979                                                   980 
980     if ($sphinx_major < 3) {                      981     if ($sphinx_major < 3) {
981         $name = "typedef " . $args{'typedef'}; !! 982         $name = "typedef " . $args{'typedef'};
982     } else {                                      983     } else {
983         $name = $args{'typedef'};              !! 984         $name = $args{'typedef'};
984     }                                             985     }
985     print "\n\n.. c:type:: " . $name . "\n\n";    986     print "\n\n.. c:type:: " . $name . "\n\n";
986     print_lineno($declaration_start_line);        987     print_lineno($declaration_start_line);
987     $lineprefix = "   ";                          988     $lineprefix = "   ";
988     output_highlight_rst($args{'purpose'});       989     output_highlight_rst($args{'purpose'});
989     print "\n";                                   990     print "\n";
990                                                   991 
991     $lineprefix = $oldprefix;                     992     $lineprefix = $oldprefix;
992     output_section_rst(@_);                       993     output_section_rst(@_);
993 }                                                 994 }
994                                                   995 
995 sub output_struct_rst(%) {                        996 sub output_struct_rst(%) {
996     my %args = %{$_[0]};                          997     my %args = %{$_[0]};
997     my ($parameter);                              998     my ($parameter);
998     my $oldprefix = $lineprefix;                  999     my $oldprefix = $lineprefix;
999                                                   1000 
1000     if ($sphinx_major < 3) {                     1001     if ($sphinx_major < 3) {
1001         my $name = $args{'type'} . " " . $arg !! 1002         my $name = $args{'type'} . " " . $args{'struct'};
1002         print "\n\n.. c:type:: " . $name . "\ !! 1003         print "\n\n.. c:type:: " . $name . "\n\n";
1003     } else {                                     1004     } else {
1004         my $name = $args{'struct'};           !! 1005         my $name = $args{'struct'};
1005         if ($args{'type'} eq 'union') {       !! 1006         if ($args{'type'} eq 'union') {
1006             print "\n\n.. c:union:: " . $name !! 1007             print "\n\n.. c:union:: " . $name . "\n\n";
1007         } else {                              !! 1008         } else {
1008             print "\n\n.. c:struct:: " . $nam !! 1009             print "\n\n.. c:struct:: " . $name . "\n\n";
1009         }                                     !! 1010         }
1010     }                                            1011     }
1011     print_lineno($declaration_start_line);       1012     print_lineno($declaration_start_line);
1012     $lineprefix = "  ";                          1013     $lineprefix = "  ";
1013     output_highlight_rst($args{'purpose'});      1014     output_highlight_rst($args{'purpose'});
1014     print "\n";                                  1015     print "\n";
1015                                                  1016 
1016     print ".. container:: kernelindent\n\n";     1017     print ".. container:: kernelindent\n\n";
1017     print $lineprefix . "**Definition**::\n\n    1018     print $lineprefix . "**Definition**::\n\n";
1018     my $declaration = $args{'definition'};       1019     my $declaration = $args{'definition'};
1019     $lineprefix = $lineprefix . "  ";            1020     $lineprefix = $lineprefix . "  ";
1020     $declaration =~ s/\t/$lineprefix/g;          1021     $declaration =~ s/\t/$lineprefix/g;
1021     print $lineprefix . $args{'type'} . " " .    1022     print $lineprefix . $args{'type'} . " " . $args{'struct'} . " {\n$declaration" . $lineprefix . "};\n\n";
1022                                                  1023 
1023     $lineprefix = "  ";                          1024     $lineprefix = "  ";
1024     print $lineprefix . "**Members**\n\n";       1025     print $lineprefix . "**Members**\n\n";
1025     foreach $parameter (@{$args{'parameterlis    1026     foreach $parameter (@{$args{'parameterlist'}}) {
1026         ($parameter =~ /^#/) && next;         !! 1027         ($parameter =~ /^#/) && next;
1027                                                  1028 
1028         my $parameter_name = $parameter;      !! 1029         my $parameter_name = $parameter;
1029         $parameter_name =~ s/\[.*//;          !! 1030         $parameter_name =~ s/\[.*//;
1030                                                  1031 
1031         ($args{'parameterdescs'}{$parameter_n !! 1032         ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
1032         $type = $args{'parametertypes'}{$para !! 1033         $type = $args{'parametertypes'}{$parameter};
1033         print_lineno($parameterdesc_start_lin    1034         print_lineno($parameterdesc_start_lines{$parameter_name});
1034         print $lineprefix . "``" . $parameter !! 1035         print $lineprefix . "``" . $parameter . "``\n";
1035         $lineprefix = "    ";                 !! 1036         $lineprefix = "    ";
1036         output_highlight_rst($args{'parameter !! 1037         output_highlight_rst($args{'parameterdescs'}{$parameter_name});
1037         $lineprefix = "  ";                   !! 1038         $lineprefix = "  ";
1038         print "\n";                           !! 1039         print "\n";
1039     }                                            1040     }
1040     print "\n";                                  1041     print "\n";
1041                                                  1042 
1042     $lineprefix = $oldprefix;                    1043     $lineprefix = $oldprefix;
1043     output_section_rst(@_);                      1044     output_section_rst(@_);
1044 }                                                1045 }
1045                                                  1046 
1046 ## none mode output functions                    1047 ## none mode output functions
1047                                                  1048 
1048 sub output_function_none(%) {                    1049 sub output_function_none(%) {
1049 }                                                1050 }
1050                                                  1051 
1051 sub output_enum_none(%) {                        1052 sub output_enum_none(%) {
1052 }                                                1053 }
1053                                                  1054 
1054 sub output_typedef_none(%) {                     1055 sub output_typedef_none(%) {
1055 }                                                1056 }
1056                                                  1057 
1057 sub output_struct_none(%) {                      1058 sub output_struct_none(%) {
1058 }                                                1059 }
1059                                                  1060 
1060 sub output_blockhead_none(%) {                   1061 sub output_blockhead_none(%) {
1061 }                                                1062 }
1062                                                  1063 
1063 ##                                               1064 ##
1064 # generic output function for all types (func    1065 # generic output function for all types (function, struct/union, typedef, enum);
1065 # calls the generated, variable output_ funct    1066 # calls the generated, variable output_ function name based on
1066 # functype and output_mode                       1067 # functype and output_mode
1067 sub output_declaration {                         1068 sub output_declaration {
1068     no strict 'refs';                            1069     no strict 'refs';
1069     my $name = shift;                            1070     my $name = shift;
1070     my $functype = shift;                        1071     my $functype = shift;
1071     my $func = "output_${functype}_$output_mo    1072     my $func = "output_${functype}_$output_mode";
1072                                                  1073 
1073     return if (defined($nosymbol_table{$name}    1074     return if (defined($nosymbol_table{$name}));
1074                                                  1075 
1075     if (($output_selection == OUTPUT_ALL) ||     1076     if (($output_selection == OUTPUT_ALL) ||
1076         (($output_selection == OUTPUT_INCLUDE !! 1077         (($output_selection == OUTPUT_INCLUDE ||
1077           $output_selection == OUTPUT_EXPORTE !! 1078           $output_selection == OUTPUT_EXPORTED) &&
1078          defined($function_table{$name})) ||  !! 1079          defined($function_table{$name})) ||
1079         ($output_selection == OUTPUT_INTERNAL !! 1080         ($output_selection == OUTPUT_INTERNAL &&
1080          !($functype eq "function" && defined !! 1081          !($functype eq "function" && defined($function_table{$name}))))
1081     {                                            1082     {
1082         &$func(@_);                           !! 1083         &$func(@_);
1083         $section_counter++;                   !! 1084         $section_counter++;
1084     }                                            1085     }
1085 }                                                1086 }
1086                                                  1087 
1087 ##                                               1088 ##
1088 # generic output function - calls the right o    1089 # generic output function - calls the right one based on current output mode.
1089 sub output_blockhead {                           1090 sub output_blockhead {
1090     no strict 'refs';                            1091     no strict 'refs';
1091     my $func = "output_blockhead_" . $output_    1092     my $func = "output_blockhead_" . $output_mode;
1092     &$func(@_);                                  1093     &$func(@_);
1093     $section_counter++;                          1094     $section_counter++;
1094 }                                                1095 }
1095                                                  1096 
1096 ##                                               1097 ##
1097 # takes a declaration (struct, union, enum, t    1098 # takes a declaration (struct, union, enum, typedef) and
1098 # invokes the right handler. NOT called for f    1099 # invokes the right handler. NOT called for functions.
1099 sub dump_declaration($$) {                       1100 sub dump_declaration($$) {
1100     no strict 'refs';                            1101     no strict 'refs';
1101     my ($prototype, $file) = @_;                 1102     my ($prototype, $file) = @_;
1102     my $func = "dump_" . $decl_type;             1103     my $func = "dump_" . $decl_type;
1103     &$func(@_);                                  1104     &$func(@_);
1104 }                                                1105 }
1105                                                  1106 
1106 sub dump_union($$) {                             1107 sub dump_union($$) {
1107     dump_struct(@_);                             1108     dump_struct(@_);
1108 }                                                1109 }
1109                                                  1110 
1110 sub dump_struct($$) {                            1111 sub dump_struct($$) {
1111     my $x = shift;                               1112     my $x = shift;
1112     my $file = shift;                            1113     my $file = shift;
1113     my $decl_type;                               1114     my $decl_type;
1114     my $members;                                 1115     my $members;
1115     my $type = qr{struct|union};                 1116     my $type = qr{struct|union};
1116     # For capturing struct/union definition b    1117     # For capturing struct/union definition body, i.e. "{members*}qualifiers*"
1117     my $qualifiers = qr{$attribute|__packed|_    1118     my $qualifiers = qr{$attribute|__packed|__aligned|____cacheline_aligned_in_smp|____cacheline_aligned};
1118     my $definition_body = qr{\{(.*)\}\s*$qual    1119     my $definition_body = qr{\{(.*)\}\s*$qualifiers*};
1119     my $struct_members = qr{($type)([^\{\};]+    1120     my $struct_members = qr{($type)([^\{\};]+)\{([^\{\}]*)\}([^\{\}\;]*)\;};
1120                                                  1121 
1121     if ($x =~ /($type)\s+(\w+)\s*$definition_    1122     if ($x =~ /($type)\s+(\w+)\s*$definition_body/) {
1122         $decl_type = $1;                      !! 1123         $decl_type = $1;
1123         $declaration_name = $2;               !! 1124         $declaration_name = $2;
1124         $members = $3;                        !! 1125         $members = $3;
1125     } elsif ($x =~ /typedef\s+($type)\s*$defi    1126     } elsif ($x =~ /typedef\s+($type)\s*$definition_body\s*(\w+)\s*;/) {
1126         $decl_type = $1;                      !! 1127         $decl_type = $1;
1127         $declaration_name = $3;               !! 1128         $declaration_name = $3;
1128         $members = $2;                        !! 1129         $members = $2;
1129     }                                            1130     }
1130                                                  1131 
1131     if ($members) {                              1132     if ($members) {
1132         if ($identifier ne $declaration_name) !! 1133         if ($identifier ne $declaration_name) {
1133             emit_warning("${file}:$.", "expec !! 1134             emit_warning("${file}:$.", "expecting prototype for $decl_type $identifier. Prototype was for $decl_type $declaration_name instead\n");
1134             return;                           !! 1135             return;
1135         }                                     !! 1136         }
1136                                               !! 1137 
1137         # ignore members marked private:      !! 1138         # ignore members marked private:
1138         $members =~ s/\/\*\s*private:.*?\/\*\ !! 1139         $members =~ s/\/\*\s*private:.*?\/\*\s*public:.*?\*\///gosi;
1139         $members =~ s/\/\*\s*private:.*//gosi !! 1140         $members =~ s/\/\*\s*private:.*//gosi;
1140         # strip comments:                     !! 1141         # strip comments:
1141         $members =~ s/\/\*.*?\*\///gos;       !! 1142         $members =~ s/\/\*.*?\*\///gos;
1142         # strip attributes                    !! 1143         # strip attributes
1143         $members =~ s/\s*$attribute/ /gi;     !! 1144         $members =~ s/\s*$attribute/ /gi;
1144         $members =~ s/\s*__aligned\s*\([^;]*\ !! 1145         $members =~ s/\s*__aligned\s*\([^;]*\)/ /gos;
1145         $members =~ s/\s*__counted_by\s*\([^; !! 1146         $members =~ s/\s*__packed\s*/ /gos;
1146         $members =~ s/\s*__counted_by_(le|be) !! 1147         $members =~ s/\s*CRYPTO_MINALIGN_ATTR/ /gos;
1147         $members =~ s/\s*__packed\s*/ /gos;   !! 1148         $members =~ s/\s*____cacheline_aligned_in_smp/ /gos;
1148         $members =~ s/\s*CRYPTO_MINALIGN_ATTR !! 1149         $members =~ s/\s*____cacheline_aligned/ /gos;
1149         $members =~ s/\s*____cacheline_aligne !! 1150         # unwrap struct_group():
1150         $members =~ s/\s*____cacheline_aligne !! 1151         # - first eat non-declaration parameters and rewrite for final match
1151         # unwrap struct_group():              !! 1152         # - then remove macro, outer parens, and trailing semicolon
1152         # - first eat non-declaration paramet !! 1153         $members =~ s/\bstruct_group\s*\(([^,]*,)/STRUCT_GROUP(/gos;
1153         # - then remove macro, outer parens,  !! 1154         $members =~ s/\bstruct_group_(attr|tagged)\s*\(([^,]*,){2}/STRUCT_GROUP(/gos;
1154         $members =~ s/\bstruct_group\s*\(([^, !! 1155         $members =~ s/\b__struct_group\s*\(([^,]*,){3}/STRUCT_GROUP(/gos;
1155         $members =~ s/\bstruct_group_attr\s*\ !! 1156         $members =~ s/\bSTRUCT_GROUP(\(((?:(?>[^)(]+)|(?1))*)\))[^;]*;/$2/gos;
1156         $members =~ s/\bstruct_group_tagged\s !! 1157 
1157         $members =~ s/\b__struct_group\s*\(([ !! 1158         my $args = qr{([^,)]+)};
1158         $members =~ s/\bSTRUCT_GROUP(\(((?:(? !! 1159         # replace DECLARE_BITMAP
1159                                               !! 1160         $members =~ s/__ETHTOOL_DECLARE_LINK_MODE_MASK\s*\(([^\)]+)\)/DECLARE_BITMAP($1, __ETHTOOL_LINK_MODE_MASK_NBITS)/gos;
1160         my $args = qr{([^,)]+)};              !! 1161         $members =~ s/DECLARE_PHY_INTERFACE_MASK\s*\(([^\)]+)\)/DECLARE_BITMAP($1, PHY_INTERFACE_MODE_MAX)/gos;
1161         # replace DECLARE_BITMAP              !! 1162         $members =~ s/DECLARE_BITMAP\s*\($args,\s*$args\)/unsigned long $1\[BITS_TO_LONGS($2)\]/gos;
1162         $members =~ s/__ETHTOOL_DECLARE_LINK_ !! 1163         # replace DECLARE_HASHTABLE
1163         $members =~ s/DECLARE_PHY_INTERFACE_M !! 1164         $members =~ s/DECLARE_HASHTABLE\s*\($args,\s*$args\)/unsigned long $1\[1 << (($2) - 1)\]/gos;
1164         $members =~ s/DECLARE_BITMAP\s*\($arg !! 1165         # replace DECLARE_KFIFO
1165         # replace DECLARE_HASHTABLE           !! 1166         $members =~ s/DECLARE_KFIFO\s*\($args,\s*$args,\s*$args\)/$2 \*$1/gos;
1166         $members =~ s/DECLARE_HASHTABLE\s*\($ !! 1167         # replace DECLARE_KFIFO_PTR
1167         # replace DECLARE_KFIFO               !! 1168         $members =~ s/DECLARE_KFIFO_PTR\s*\($args,\s*$args\)/$2 \*$1/gos;
1168         $members =~ s/DECLARE_KFIFO\s*\($args !! 1169         # replace DECLARE_FLEX_ARRAY
1169         # replace DECLARE_KFIFO_PTR           !! 1170         $members =~ s/(?:__)?DECLARE_FLEX_ARRAY\s*\($args,\s*$args\)/$1 $2\[\]/gos;
1170         $members =~ s/DECLARE_KFIFO_PTR\s*\($ !! 1171         my $declaration = $members;
1171         # replace DECLARE_FLEX_ARRAY          !! 1172 
1172         $members =~ s/(?:__)?DECLARE_FLEX_ARR !! 1173         # Split nested struct/union elements as newer ones
1173         #replace DEFINE_DMA_UNMAP_ADDR        !! 1174         while ($members =~ m/$struct_members/) {
1174         $members =~ s/DEFINE_DMA_UNMAP_ADDR\s !! 1175                 my $newmember;
1175         #replace DEFINE_DMA_UNMAP_LEN         !! 1176                 my $maintype = $1;
1176         $members =~ s/DEFINE_DMA_UNMAP_LEN\s* !! 1177                 my $ids = $4;
1177         my $declaration = $members;           !! 1178                 my $content = $3;
1178                                               !! 1179                 foreach my $id(split /,/, $ids) {
1179         # Split nested struct/union elements  !! 1180                         $newmember .= "$maintype $id; ";
1180         while ($members =~ m/$struct_members/ !! 1181 
1181             my $newmember;                    !! 1182                         $id =~ s/[:\[].*//;
1182             my $maintype = $1;                !! 1183                         $id =~ s/^\s*\**(\S+)\s*/$1/;
1183             my $ids = $4;                     !! 1184                         foreach my $arg (split /;/, $content) {
1184             my $content = $3;                 !! 1185                                 next if ($arg =~ m/^\s*$/);
1185             foreach my $id(split /,/, $ids) { !! 1186                                 if ($arg =~ m/^([^\(]+\(\*?\s*)([\w\.]*)(\s*\).*)/) {
1186                 $newmember .= "$maintype $id; !! 1187                                         # pointer-to-function
1187                                               !! 1188                                         my $type = $1;
1188                 $id =~ s/[:\[].*//;           !! 1189                                         my $name = $2;
1189                 $id =~ s/^\s*\**(\S+)\s*/$1/; !! 1190                                         my $extra = $3;
1190                 foreach my $arg (split /;/, $ !! 1191                                         next if (!$name);
1191                     next if ($arg =~ m/^\s*$/ !! 1192                                         if ($id =~ m/^\s*$/) {
1192                     if ($arg =~ m/^([^\(]+\(\ !! 1193                                                 # anonymous struct/union
1193                         # pointer-to-function !! 1194                                                 $newmember .= "$type$name$extra; ";
1194                         my $type = $1;        !! 1195                                         } else {
1195                         my $name = $2;        !! 1196                                                 $newmember .= "$type$id.$name$extra; ";
1196                         my $extra = $3;       !! 1197                                         }
1197                         next if (!$name);     !! 1198                                 } else {
1198                         if ($id =~ m/^\s*$/)  !! 1199                                         my $type;
1199                             # anonymous struc !! 1200                                         my $names;
1200                             $newmember .= "$t !! 1201                                         $arg =~ s/^\s+//;
1201                         } else {              !! 1202                                         $arg =~ s/\s+$//;
1202                             $newmember .= "$t !! 1203                                         # Handle bitmaps
1203                         }                     !! 1204                                         $arg =~ s/:\s*\d+\s*//g;
1204                     } else {                  !! 1205                                         # Handle arrays
1205                         my $type;             !! 1206                                         $arg =~ s/\[.*\]//g;
1206                         my $names;            !! 1207                                         # The type may have multiple words,
1207                         $arg =~ s/^\s+//;     !! 1208                                         # and multiple IDs can be defined, like:
1208                         $arg =~ s/\s+$//;     !! 1209                                         #       const struct foo, *bar, foobar
1209                         # Handle bitmaps      !! 1210                                         # So, we remove spaces when parsing the
1210                         $arg =~ s/:\s*\d+\s*/ !! 1211                                         # names, in order to match just names
1211                         # Handle arrays       !! 1212                                         # and commas for the names
1212                         $arg =~ s/\[.*\]//g;  !! 1213                                         $arg =~ s/\s*,\s*/,/g;
1213                         # The type may have m !! 1214                                         if ($arg =~ m/(.*)\s+([\S+,]+)/) {
1214                         # and multiple IDs ca !! 1215                                                 $type = $1;
1215                         #    const struct foo !! 1216                                                 $names = $2;
1216                         # So, we remove space !! 1217                                         } else {
1217                         # names, in order to  !! 1218                                                 $newmember .= "$arg; ";
1218                         # and commas for the  !! 1219                                                 next;
1219                         $arg =~ s/\s*,\s*/,/g !! 1220                                         }
1220                         if ($arg =~ m/(.*)\s+ !! 1221                                         foreach my $name (split /,/, $names) {
1221                             $type = $1;       !! 1222                                                 $name =~ s/^\s*\**(\S+)\s*/$1/;
1222                             $names = $2;      !! 1223                                                 next if (($name =~ m/^\s*$/));
1223                         } else {              !! 1224                                                 if ($id =~ m/^\s*$/) {
1224                             $newmember .= "$a !! 1225                                                         # anonymous struct/union
1225                             next;             !! 1226                                                         $newmember .= "$type $name; ";
1226                         }                     !! 1227                                                 } else {
1227                         foreach my $name (spl !! 1228                                                         $newmember .= "$type $id.$name; ";
1228                             $name =~ s/^\s*\* !! 1229                                                 }
1229                             next if (($name = !! 1230                                         }
1230                             if ($id =~ m/^\s* !! 1231                                 }
1231                                 # anonymous s !! 1232                         }
1232                                 $newmember .= !! 1233                 }
1233                             } else {          !! 1234                 $members =~ s/$struct_members/$newmember/;
1234                                 $newmember .= !! 1235         }
1235                             }                 !! 1236 
1236                         }                     !! 1237         # Ignore other nested elements, like enums
1237                     }                         !! 1238         $members =~ s/(\{[^\{\}]*\})//g;
1238                 }                             !! 1239 
1239             }                                 !! 1240         create_parameterlist($members, ';', $file, $declaration_name);
1240             $members =~ s/$struct_members/$ne !! 1241         check_sections($file, $declaration_name, $decl_type, $sectcheck, $struct_actual);
1241         }                                     !! 1242 
1242                                               !! 1243         # Adjust declaration for better display
1243         # Ignore other nested elements, like  !! 1244         $declaration =~ s/([\{;])/$1\n/g;
1244         $members =~ s/(\{[^\{\}]*\})//g;      !! 1245         $declaration =~ s/\}\s+;/};/g;
1245                                               !! 1246         # Better handle inlined enums
1246         create_parameterlist($members, ';', $ !! 1247         do {} while ($declaration =~ s/(enum\s+\{[^\}]+),([^\n])/$1,\n$2/);
1247         check_sections($file, $declaration_na !! 1248 
1248                                               !! 1249         my @def_args = split /\n/, $declaration;
1249         # Adjust declaration for better displ !! 1250         my $level = 1;
1250         $declaration =~ s/([\{;])/$1\n/g;     !! 1251         $declaration = "";
1251         $declaration =~ s/\}\s+;/};/g;        !! 1252         foreach my $clause (@def_args) {
1252         # Better handle inlined enums         !! 1253                 $clause =~ s/^\s+//;
1253         do {} while ($declaration =~ s/(enum\ !! 1254                 $clause =~ s/\s+$//;
1254                                               !! 1255                 $clause =~ s/\s+/ /;
1255         my @def_args = split /\n/, $declarati !! 1256                 next if (!$clause);
1256         my $level = 1;                        !! 1257                 $level-- if ($clause =~ m/(\})/ && $level > 1);
1257         $declaration = "";                    !! 1258                 if (!($clause =~ m/^\s*#/)) {
1258         foreach my $clause (@def_args) {      !! 1259                         $declaration .= "\t" x $level;
1259             $clause =~ s/^\s+//;              !! 1260                 }
1260             $clause =~ s/\s+$//;              !! 1261                 $declaration .= "\t" . $clause . "\n";
1261             $clause =~ s/\s+/ /;              !! 1262                 $level++ if ($clause =~ m/(\{)/ && !($clause =~m/\}/));
1262             next if (!$clause);               !! 1263         }
1263             $level-- if ($clause =~ m/(\})/ & !! 1264         output_declaration($declaration_name,
1264             if (!($clause =~ m/^\s*#/)) {     !! 1265                            'struct',
1265                 $declaration .= "\t" x $level !! 1266                            {'struct' => $declaration_name,
1266             }                                 !! 1267                             'module' => $modulename,
1267             $declaration .= "\t" . $clause .  !! 1268                             'definition' => $declaration,
1268             $level++ if ($clause =~ m/(\{)/ & !! 1269                             'parameterlist' => \@parameterlist,
1269         }                                     !! 1270                             'parameterdescs' => \%parameterdescs,
1270         output_declaration($declaration_name, !! 1271                             'parametertypes' => \%parametertypes,
1271                    'struct',                  !! 1272                             'sectionlist' => \@sectionlist,
1272                    {'struct' => $declaration_ !! 1273                             'sections' => \%sections,
1273                     'module' => $modulename,  !! 1274                             'purpose' => $declaration_purpose,
1274                     'definition' => $declarat !! 1275                             'type' => $decl_type
1275                     'parameterlist' => \@para !! 1276                            });
1276                     'parameterdescs' => \%par !! 1277     }
1277                     'parametertypes' => \%par !! 1278     else {
1278                     'sectionlist' => \@sectio !! 1279         print STDERR "${file}:$.: error: Cannot parse struct or union!\n";
1279                     'sections' => \%sections, !! 1280         ++$errors;
1280                     'purpose' => $declaration << 
1281                     'type' => $decl_type      << 
1282                    });                        << 
1283     } else {                                  << 
1284         print STDERR "${file}:$.: error: Cann << 
1285         ++$errors;                            << 
1286     }                                            1281     }
1287 }                                                1282 }
1288                                                  1283 
1289                                                  1284 
1290 sub show_warnings($$) {                          1285 sub show_warnings($$) {
1291     my $functype = shift;                     !! 1286         my $functype = shift;
1292     my $name = shift;                         !! 1287         my $name = shift;
1293                                                  1288 
1294     return 0 if (defined($nosymbol_table{$nam !! 1289         return 0 if (defined($nosymbol_table{$name}));
1295                                                  1290 
1296     return 1 if ($output_selection == OUTPUT_ !! 1291         return 1 if ($output_selection == OUTPUT_ALL);
1297                                                  1292 
1298     if ($output_selection == OUTPUT_EXPORTED) !! 1293         if ($output_selection == OUTPUT_EXPORTED) {
1299         if (defined($function_table{$name}))  !! 1294                 if (defined($function_table{$name})) {
1300             return 1;                         !! 1295                         return 1;
1301         } else {                              !! 1296                 } else {
1302             return 0;                         !! 1297                         return 0;
1303         }                                     !! 1298                 }
1304     }                                         !! 1299         }
1305     if ($output_selection == OUTPUT_INTERNAL) !! 1300         if ($output_selection == OUTPUT_INTERNAL) {
1306         if (!($functype eq "function" && defi !! 1301                 if (!($functype eq "function" && defined($function_table{$name}))) {
1307             return 1;                         !! 1302                         return 1;
1308         } else {                              !! 1303                 } else {
1309             return 0;                         !! 1304                         return 0;
1310         }                                     !! 1305                 }
1311     }                                         !! 1306         }
1312     if ($output_selection == OUTPUT_INCLUDE)  !! 1307         if ($output_selection == OUTPUT_INCLUDE) {
1313         if (defined($function_table{$name}))  !! 1308                 if (defined($function_table{$name})) {
1314             return 1;                         !! 1309                         return 1;
1315         } else {                              !! 1310                 } else {
1316             return 0;                         !! 1311                         return 0;
1317         }                                     !! 1312                 }
1318     }                                         !! 1313         }
1319     die("Please add the new output type at sh !! 1314         die("Please add the new output type at show_warnings()");
1320 }                                                1315 }
1321                                                  1316 
1322 sub dump_enum($$) {                              1317 sub dump_enum($$) {
1323     my $x = shift;                               1318     my $x = shift;
1324     my $file = shift;                            1319     my $file = shift;
1325     my $members;                                 1320     my $members;
1326                                                  1321 
1327     # ignore members marked private:             1322     # ignore members marked private:
1328     $x =~ s/\/\*\s*private:.*?\/\*\s*public:.    1323     $x =~ s/\/\*\s*private:.*?\/\*\s*public:.*?\*\///gosi;
1329     $x =~ s/\/\*\s*private:.*}/}/gosi;           1324     $x =~ s/\/\*\s*private:.*}/}/gosi;
1330                                                  1325 
1331     $x =~ s@/\*.*?\*/@@gos;     # strip comme    1326     $x =~ s@/\*.*?\*/@@gos;     # strip comments.
1332     # strip #define macros inside enums          1327     # strip #define macros inside enums
1333     $x =~ s@#\s*((define|ifdef|if)\s+|endif)[ !! 1328     $x =~ s@#\s*((define|ifdef)\s+|endif)[^;]*;@@gos;
1334                                                  1329 
1335     if ($x =~ /typedef\s+enum\s*\{(.*)\}\s*(\    1330     if ($x =~ /typedef\s+enum\s*\{(.*)\}\s*(\w*)\s*;/) {
1336         $declaration_name = $2;               !! 1331         $declaration_name = $2;
1337         $members = $1;                        !! 1332         $members = $1;
1338     } elsif ($x =~ /enum\s+(\w*)\s*\{(.*)\}/)    1333     } elsif ($x =~ /enum\s+(\w*)\s*\{(.*)\}/) {
1339         $declaration_name = $1;               !! 1334         $declaration_name = $1;
1340         $members = $2;                        !! 1335         $members = $2;
1341     }                                            1336     }
1342                                                  1337 
1343     if ($members) {                              1338     if ($members) {
1344         if ($identifier ne $declaration_name) !! 1339         if ($identifier ne $declaration_name) {
1345             if ($identifier eq "") {          !! 1340             if ($identifier eq "") {
1346                 emit_warning("${file}:$.", "w !! 1341                 emit_warning("${file}:$.", "wrong kernel-doc identifier on line:\n");
1347             } else {                          !! 1342             } else {
1348                 emit_warning("${file}:$.", "e !! 1343                 emit_warning("${file}:$.", "expecting prototype for enum $identifier. Prototype was for enum $declaration_name instead\n");
1349             }                                 !! 1344             }
1350             return;                           !! 1345             return;
1351         }                                     !! 1346         }
1352         $declaration_name = "(anonymous)" if  !! 1347         $declaration_name = "(anonymous)" if ($declaration_name eq "");
1353                                               !! 1348 
1354         my %_members;                         !! 1349         my %_members;
1355                                               !! 1350 
1356         $members =~ s/\s+$//;                 !! 1351         $members =~ s/\s+$//;
1357         $members =~ s/\([^;]*?[\)]//g;        !! 1352 
1358                                               !! 1353         foreach my $arg (split ',', $members) {
1359         foreach my $arg (split ',', $members) !! 1354             $arg =~ s/^\s*(\w+).*/$1/;
1360             $arg =~ s/^\s*(\w+).*/$1/;        !! 1355             push @parameterlist, $arg;
1361             push @parameterlist, $arg;        !! 1356             if (!$parameterdescs{$arg}) {
1362             if (!$parameterdescs{$arg}) {     !! 1357                 $parameterdescs{$arg} = $undescribed;
1363                 $parameterdescs{$arg} = $unde !! 1358                 if (show_warnings("enum", $declaration_name)) {
1364                 if (show_warnings("enum", $de !! 1359                         emit_warning("${file}:$.", "Enum value '$arg' not described in enum '$declaration_name'\n");
1365                     emit_warning("${file}:$." !! 1360                 }
1366                 }                             !! 1361             }
1367             }                                 !! 1362             $_members{$arg} = 1;
1368             $_members{$arg} = 1;              !! 1363         }
1369         }                                     !! 1364 
1370                                               !! 1365         while (my ($k, $v) = each %parameterdescs) {
1371         while (my ($k, $v) = each %parameterd !! 1366             if (!exists($_members{$k})) {
1372             if (!exists($_members{$k})) {     !! 1367                 if (show_warnings("enum", $declaration_name)) {
1373                 if (show_warnings("enum", $de !! 1368                      emit_warning("${file}:$.", "Excess enum value '$k' description in '$declaration_name'\n");
1374                     emit_warning("${file}:$." !! 1369                 }
1375                 }                             !! 1370             }
1376             }                                 !! 1371         }
1377         }                                     !! 1372 
1378                                               !! 1373         output_declaration($declaration_name,
1379         output_declaration($declaration_name, !! 1374                            'enum',
1380                            'enum',            !! 1375                            {'enum' => $declaration_name,
1381                            {'enum' => $declar !! 1376                             'module' => $modulename,
1382                             'module' => $modu !! 1377                             'parameterlist' => \@parameterlist,
1383                             'parameterlist' = !! 1378                             'parameterdescs' => \%parameterdescs,
1384                             'parameterdescs'  !! 1379                             'sectionlist' => \@sectionlist,
1385                             'sectionlist' =>  !! 1380                             'sections' => \%sections,
1386                             'sections' => \%s !! 1381                             'purpose' => $declaration_purpose
1387                             'purpose' => $dec !! 1382                            });
1388                            });                << 
1389     } else {                                     1383     } else {
1390         print STDERR "${file}:$.: error: Cann !! 1384         print STDERR "${file}:$.: error: Cannot parse enum!\n";
1391         ++$errors;                            !! 1385         ++$errors;
1392     }                                            1386     }
1393 }                                                1387 }
1394                                                  1388 
1395 my $typedef_type = qr { ((?:\s+[\w\*]+\b){1,8    1389 my $typedef_type = qr { ((?:\s+[\w\*]+\b){1,8})\s* }x;
1396 my $typedef_ident = qr { \*?\s*(\w\S+)\s* }x;    1390 my $typedef_ident = qr { \*?\s*(\w\S+)\s* }x;
1397 my $typedef_args = qr { \s*\((.*)\); }x;         1391 my $typedef_args = qr { \s*\((.*)\); }x;
1398                                                  1392 
1399 my $typedef1 = qr { typedef$typedef_type\($ty    1393 my $typedef1 = qr { typedef$typedef_type\($typedef_ident\)$typedef_args }x;
1400 my $typedef2 = qr { typedef$typedef_type$type    1394 my $typedef2 = qr { typedef$typedef_type$typedef_ident$typedef_args }x;
1401                                                  1395 
1402 sub dump_typedef($$) {                           1396 sub dump_typedef($$) {
1403     my $x = shift;                               1397     my $x = shift;
1404     my $file = shift;                            1398     my $file = shift;
1405                                                  1399 
1406     $x =~ s@/\*.*?\*/@@gos;     # strip comme    1400     $x =~ s@/\*.*?\*/@@gos;     # strip comments.
1407                                                  1401 
1408     # Parse function typedef prototypes          1402     # Parse function typedef prototypes
1409     if ($x =~ $typedef1 || $x =~ $typedef2) {    1403     if ($x =~ $typedef1 || $x =~ $typedef2) {
1410         $return_type = $1;                    !! 1404         $return_type = $1;
1411         $declaration_name = $2;               !! 1405         $declaration_name = $2;
1412         my $args = $3;                        !! 1406         my $args = $3;
1413         $return_type =~ s/^\s+//;             !! 1407         $return_type =~ s/^\s+//;
1414                                               !! 1408 
1415         if ($identifier ne $declaration_name) !! 1409         if ($identifier ne $declaration_name) {
1416             emit_warning("${file}:$.", "expec !! 1410             emit_warning("${file}:$.", "expecting prototype for typedef $identifier. Prototype was for typedef $declaration_name instead\n");
1417             return;                           !! 1411             return;
1418         }                                     !! 1412         }
1419                                               !! 1413 
1420         create_parameterlist($args, ',', $fil !! 1414         create_parameterlist($args, ',', $file, $declaration_name);
1421                                               !! 1415 
1422         output_declaration($declaration_name, !! 1416         output_declaration($declaration_name,
1423                            'function',        !! 1417                            'function',
1424                            {'function' => $de !! 1418                            {'function' => $declaration_name,
1425                             'typedef' => 1,   !! 1419                             'typedef' => 1,
1426                             'module' => $modu !! 1420                             'module' => $modulename,
1427                             'functiontype' => !! 1421                             'functiontype' => $return_type,
1428                             'parameterlist' = !! 1422                             'parameterlist' => \@parameterlist,
1429                             'parameterdescs'  !! 1423                             'parameterdescs' => \%parameterdescs,
1430                             'parametertypes'  !! 1424                             'parametertypes' => \%parametertypes,
1431                             'sectionlist' =>  !! 1425                             'sectionlist' => \@sectionlist,
1432                             'sections' => \%s !! 1426                             'sections' => \%sections,
1433                             'purpose' => $dec !! 1427                             'purpose' => $declaration_purpose
1434                            });                !! 1428                            });
1435         return;                               !! 1429         return;
1436     }                                            1430     }
1437                                                  1431 
1438     while (($x =~ /\(*.\)\s*;$/) || ($x =~ /\    1432     while (($x =~ /\(*.\)\s*;$/) || ($x =~ /\[*.\]\s*;$/)) {
1439         $x =~ s/\(*.\)\s*;$/;/;               !! 1433         $x =~ s/\(*.\)\s*;$/;/;
1440         $x =~ s/\[*.\]\s*;$/;/;               !! 1434         $x =~ s/\[*.\]\s*;$/;/;
1441     }                                            1435     }
1442                                                  1436 
1443     if ($x =~ /typedef.*\s+(\w+)\s*;/) {         1437     if ($x =~ /typedef.*\s+(\w+)\s*;/) {
1444         $declaration_name = $1;               !! 1438         $declaration_name = $1;
1445                                                  1439 
1446         if ($identifier ne $declaration_name) !! 1440         if ($identifier ne $declaration_name) {
1447             emit_warning("${file}:$.", "expec !! 1441             emit_warning("${file}:$.", "expecting prototype for typedef $identifier. Prototype was for typedef $declaration_name instead\n");
1448             return;                           !! 1442             return;
1449         }                                     !! 1443         }
1450                                               !! 1444 
1451         output_declaration($declaration_name, !! 1445         output_declaration($declaration_name,
1452                            'typedef',         !! 1446                            'typedef',
1453                            {'typedef' => $dec !! 1447                            {'typedef' => $declaration_name,
1454                             'module' => $modu !! 1448                             'module' => $modulename,
1455                             'sectionlist' =>  !! 1449                             'sectionlist' => \@sectionlist,
1456                             'sections' => \%s !! 1450                             'sections' => \%sections,
1457                             'purpose' => $dec !! 1451                             'purpose' => $declaration_purpose
1458                            });                !! 1452                            });
1459     } else {                                  !! 1453     }
1460         print STDERR "${file}:$.: error: Cann !! 1454     else {
1461         ++$errors;                            !! 1455         print STDERR "${file}:$.: error: Cannot parse typedef!\n";
                                                   >> 1456         ++$errors;
1462     }                                            1457     }
1463 }                                                1458 }
1464                                                  1459 
1465 sub save_struct_actual($) {                      1460 sub save_struct_actual($) {
1466     my $actual = shift;                          1461     my $actual = shift;
1467                                                  1462 
1468     # strip all spaces from the actual param     1463     # strip all spaces from the actual param so that it looks like one string item
1469     $actual =~ s/\s*//g;                         1464     $actual =~ s/\s*//g;
1470     $struct_actual = $struct_actual . $actual    1465     $struct_actual = $struct_actual . $actual . " ";
1471 }                                                1466 }
1472                                                  1467 
1473 sub create_parameterlist($$$$) {                 1468 sub create_parameterlist($$$$) {
1474     my $args = shift;                            1469     my $args = shift;
1475     my $splitter = shift;                        1470     my $splitter = shift;
1476     my $file = shift;                            1471     my $file = shift;
1477     my $declaration_name = shift;                1472     my $declaration_name = shift;
1478     my $type;                                    1473     my $type;
1479     my $param;                                   1474     my $param;
1480                                                  1475 
1481     # temporarily replace commas inside funct    1476     # temporarily replace commas inside function pointer definition
1482     my $arg_expr = qr{\([^\),]+};                1477     my $arg_expr = qr{\([^\),]+};
1483     while ($args =~ /$arg_expr,/) {              1478     while ($args =~ /$arg_expr,/) {
1484         $args =~ s/($arg_expr),/$1#/g;        !! 1479         $args =~ s/($arg_expr),/$1#/g;
1485     }                                            1480     }
1486                                                  1481 
1487     foreach my $arg (split($splitter, $args))    1482     foreach my $arg (split($splitter, $args)) {
1488         # strip comments                      !! 1483         # strip comments
1489         $arg =~ s/\/\*.*\*\///;               !! 1484         $arg =~ s/\/\*.*\*\///;
1490         # ignore argument attributes          !! 1485         # ignore argument attributes
1491         $arg =~ s/\sPOS0?\s/ /;               !! 1486         $arg =~ s/\sPOS0?\s/ /;
1492         # strip leading/trailing spaces       !! 1487         # strip leading/trailing spaces
1493         $arg =~ s/^\s*//;                     !! 1488         $arg =~ s/^\s*//;
1494         $arg =~ s/\s*$//;                     !! 1489         $arg =~ s/\s*$//;
1495         $arg =~ s/\s+/ /;                     !! 1490         $arg =~ s/\s+/ /;
1496                                               !! 1491 
1497         if ($arg =~ /^#/) {                   !! 1492         if ($arg =~ /^#/) {
1498             # Treat preprocessor directive as !! 1493             # Treat preprocessor directive as a typeless variable just to fill
1499             # corresponding data structures " !! 1494             # corresponding data structures "correctly". Catch it later in
1500             # output_* subs.                  !! 1495             # output_* subs.
1501             push_parameter($arg, "", "", $fil !! 1496             push_parameter($arg, "", "", $file);
1502         } elsif ($arg =~ m/\(.+\)\s*\(/) {    !! 1497         } elsif ($arg =~ m/\(.+\)\s*\(/) {
1503             # pointer-to-function             !! 1498             # pointer-to-function
1504             $arg =~ tr/#/,/;                  !! 1499             $arg =~ tr/#/,/;
1505             $arg =~ m/[^\(]+\(\*?\s*([\w\[\]\ !! 1500             $arg =~ m/[^\(]+\(\*?\s*([\w\[\]\.]*)\s*\)/;
1506             $param = $1;                      !! 1501             $param = $1;
1507             $type = $arg;                     !! 1502             $type = $arg;
1508             $type =~ s/([^\(]+\(\*?)\s*$param !! 1503             $type =~ s/([^\(]+\(\*?)\s*$param/$1/;
1509             save_struct_actual($param);       !! 1504             save_struct_actual($param);
1510             push_parameter($param, $type, $ar !! 1505             push_parameter($param, $type, $arg, $file, $declaration_name);
1511         } elsif ($arg =~ m/\(.+\)\s*\[/) {    !! 1506         } elsif ($arg) {
1512             # array-of-pointers               !! 1507             $arg =~ s/\s*:\s*/:/g;
1513             $arg =~ tr/#/,/;                  !! 1508             $arg =~ s/\s*\[/\[/g;
1514             $arg =~ m/[^\(]+\(\s*\*\s*([\w\[\ !! 1509 
1515             $param = $1;                      !! 1510             my @args = split('\s*,\s*', $arg);
1516             $type = $arg;                     !! 1511             if ($args[0] =~ m/\*/) {
1517             $type =~ s/([^\(]+\(\*?)\s*$param !! 1512                 $args[0] =~ s/(\*+)\s*/ $1/;
1518             save_struct_actual($param);       !! 1513             }
1519             push_parameter($param, $type, $ar !! 1514 
1520         } elsif ($arg) {                      !! 1515             my @first_arg;
1521             $arg =~ s/\s*:\s*/:/g;            !! 1516             if ($args[0] =~ /^(.*\s+)(.*?\[.*\].*)$/) {
1522             $arg =~ s/\s*\[/\[/g;             !! 1517                     shift @args;
1523                                               !! 1518                     push(@first_arg, split('\s+', $1));
1524             my @args = split('\s*,\s*', $arg) !! 1519                     push(@first_arg, $2);
1525             if ($args[0] =~ m/\*/) {          !! 1520             } else {
1526                 $args[0] =~ s/(\*+)\s*/ $1/;  !! 1521                     @first_arg = split('\s+', shift @args);
1527             }                                 !! 1522             }
1528                                               !! 1523 
1529             my @first_arg;                    !! 1524             unshift(@args, pop @first_arg);
1530             if ($args[0] =~ /^(.*\s+)(.*?\[.* !! 1525             $type = join " ", @first_arg;
1531                 shift @args;                  !! 1526 
1532                 push(@first_arg, split('\s+', !! 1527             foreach $param (@args) {
1533                 push(@first_arg, $2);         !! 1528                 if ($param =~ m/^(\*+)\s*(.*)/) {
1534             } else {                          !! 1529                     save_struct_actual($2);
1535                 @first_arg = split('\s+', shi !! 1530 
1536             }                                 !! 1531                     push_parameter($2, "$type $1", $arg, $file, $declaration_name);
1537                                               !! 1532                 }
1538             unshift(@args, pop @first_arg);   !! 1533                 elsif ($param =~ m/(.*?):(\d+)/) {
1539             $type = join " ", @first_arg;     !! 1534                     if ($type ne "") { # skip unnamed bit-fields
1540                                               !! 1535                         save_struct_actual($1);
1541             foreach $param (@args) {          !! 1536                         push_parameter($1, "$type:$2", $arg, $file, $declaration_name)
1542                 if ($param =~ m/^(\*+)\s*(.*) !! 1537                     }
1543                     save_struct_actual($2);   !! 1538                 }
1544                                               !! 1539                 else {
1545                     push_parameter($2, "$type !! 1540                     save_struct_actual($param);
1546                 } elsif ($param =~ m/(.*?):(\ !! 1541                     push_parameter($param, $type, $arg, $file, $declaration_name);
1547                     if ($type ne "") { # skip !! 1542                 }
1548                         save_struct_actual($1 !! 1543             }
1549                         push_parameter($1, "$ !! 1544         }
1550                     }                         << 
1551                 } else {                      << 
1552                     save_struct_actual($param << 
1553                     push_parameter($param, $t << 
1554                 }                             << 
1555             }                                 << 
1556         }                                     << 
1557     }                                            1545     }
1558 }                                                1546 }
1559                                                  1547 
1560 sub push_parameter($$$$$) {                      1548 sub push_parameter($$$$$) {
1561     my $param = shift;                        !! 1549         my $param = shift;
1562     my $type = shift;                         !! 1550         my $type = shift;
1563     my $org_arg = shift;                      !! 1551         my $org_arg = shift;
1564     my $file = shift;                         !! 1552         my $file = shift;
1565     my $declaration_name = shift;             !! 1553         my $declaration_name = shift;
1566                                               !! 1554 
1567     if (($anon_struct_union == 1) && ($type e !! 1555         if (($anon_struct_union == 1) && ($type eq "") &&
1568         ($param eq "}")) {                    !! 1556             ($param eq "}")) {
1569         return;        # ignore the ending }; !! 1557                 return;         # ignore the ending }; from anon. struct/union
1570     }                                         !! 1558         }
1571                                               !! 1559 
1572     $anon_struct_union = 0;                   !! 1560         $anon_struct_union = 0;
1573     $param =~ s/[\[\)].*//;                   !! 1561         $param =~ s/[\[\)].*//;
1574                                               !! 1562 
1575     if ($type eq "" && $param =~ /\.\.\.$/)   !! 1563         if ($type eq "" && $param =~ /\.\.\.$/)
1576     {                                         !! 1564         {
1577         if (!$param =~ /\w\.\.\.$/) {         !! 1565             if (!$param =~ /\w\.\.\.$/) {
1578             # handles unnamed variable parame !! 1566               # handles unnamed variable parameters
1579             $param = "...";                   !! 1567               $param = "...";
1580         } elsif ($param =~ /\w\.\.\.$/) {     !! 1568             }
1581             # for named variable parameters o !! 1569             elsif ($param =~ /\w\.\.\.$/) {
1582             $param =~ s/\.\.\.$//;            !! 1570               # for named variable parameters of the form `x...`, remove the dots
1583         }                                     !! 1571               $param =~ s/\.\.\.$//;
1584         if (!defined $parameterdescs{$param}  !! 1572             }
1585             $parameterdescs{$param} = "variab !! 1573             if (!defined $parameterdescs{$param} || $parameterdescs{$param} eq "") {
1586         }                                     !! 1574                 $parameterdescs{$param} = "variable arguments";
1587     }                                         !! 1575             }
1588     elsif ($type eq "" && ($param eq "" or $p !! 1576         }
1589     {                                         !! 1577         elsif ($type eq "" && ($param eq "" or $param eq "void"))
1590         $param="void";                        !! 1578         {
1591         $parameterdescs{void} = "no arguments !! 1579             $param="void";
1592     }                                         !! 1580             $parameterdescs{void} = "no arguments";
1593     elsif ($type eq "" && ($param eq "struct" !! 1581         }
1594     # handle unnamed (anonymous) union or str !! 1582         elsif ($type eq "" && ($param eq "struct" or $param eq "union"))
1595     {                                         !! 1583         # handle unnamed (anonymous) union or struct:
1596         $type = $param;                       !! 1584         {
1597         $param = "{unnamed_" . $param . "}";  !! 1585                 $type = $param;
1598         $parameterdescs{$param} = "anonymous\ !! 1586                 $param = "{unnamed_" . $param . "}";
1599         $anon_struct_union = 1;               !! 1587                 $parameterdescs{$param} = "anonymous\n";
1600     }                                         !! 1588                 $anon_struct_union = 1;
1601     elsif ($param =~ "__cacheline_group" )    !! 1589         }
1602     # handle cache group enforcing variables: !! 1590 
1603     {                                         !! 1591         # warn if parameter has no description
1604         return; # ignore __cacheline_group_be !! 1592         # (but ignore ones starting with # as these are not parameters
1605     }                                         !! 1593         # but inline preprocessor statements);
1606                                               !! 1594         # Note: It will also ignore void params and unnamed structs/unions
1607     # warn if parameter has no description    !! 1595         if (!defined $parameterdescs{$param} && $param !~ /^#/) {
1608     # (but ignore ones starting with # as the !! 1596                 $parameterdescs{$param} = $undescribed;
1609     # but inline preprocessor statements);    !! 1597 
1610     # Note: It will also ignore void params a !! 1598                 if (show_warnings($type, $declaration_name) && $param !~ /\./) {
1611     if (!defined $parameterdescs{$param} && $ !! 1599                         emit_warning("${file}:$.", "Function parameter or member '$param' not described in '$declaration_name'\n");
1612         $parameterdescs{$param} = $undescribe !! 1600                 }
1613                                               !! 1601         }
1614         if (show_warnings($type, $declaration !! 1602 
1615             emit_warning("${file}:$.", "Funct !! 1603         # strip spaces from $param so that it is one continuous string
1616         }                                     !! 1604         # on @parameterlist;
1617     }                                         !! 1605         # this fixes a problem where check_sections() cannot find
1618                                               !! 1606         # a parameter like "addr[6 + 2]" because it actually appears
1619     # strip spaces from $param so that it is  !! 1607         # as "addr[6", "+", "2]" on the parameter list;
1620     # on @parameterlist;                      !! 1608         # but it's better to maintain the param string unchanged for output,
1621     # this fixes a problem where check_sectio !! 1609         # so just weaken the string compare in check_sections() to ignore
1622     # a parameter like "addr[6 + 2]" because  !! 1610         # "[blah" in a parameter string;
1623     # as "addr[6", "+", "2]" on the parameter !! 1611         ###$param =~ s/\s*//g;
1624     # but it's better to maintain the param s !! 1612         push @parameterlist, $param;
1625     # so just weaken the string compare in ch !! 1613         $org_arg =~ s/\s\s+/ /g;
1626     # "[blah" in a parameter string;          !! 1614         $parametertypes{$param} = $org_arg;
1627     ###$param =~ s/\s*//g;                    << 
1628     push @parameterlist, $param;              << 
1629     $org_arg =~ s/\s\s+/ /g;                  << 
1630     $parametertypes{$param} = $org_arg;       << 
1631 }                                                1615 }
1632                                                  1616 
1633 sub check_sections($$$$$) {                      1617 sub check_sections($$$$$) {
1634     my ($file, $decl_name, $decl_type, $sectc !! 1618         my ($file, $decl_name, $decl_type, $sectcheck, $prmscheck) = @_;
1635     my @sects = split ' ', $sectcheck;        !! 1619         my @sects = split ' ', $sectcheck;
1636     my @prms = split ' ', $prmscheck;         !! 1620         my @prms = split ' ', $prmscheck;
1637     my $err;                                  !! 1621         my $err;
1638     my ($px, $sx);                            !! 1622         my ($px, $sx);
1639     my $prm_clean;        # strip trailing "[ !! 1623         my $prm_clean;          # strip trailing "[array size]" and/or beginning "*"
1640                                               !! 1624 
1641     foreach $sx (0 .. $#sects) {              !! 1625         foreach $sx (0 .. $#sects) {
1642         $err = 1;                             !! 1626                 $err = 1;
1643         foreach $px (0 .. $#prms) {           !! 1627                 foreach $px (0 .. $#prms) {
1644             $prm_clean = $prms[$px];          !! 1628                         $prm_clean = $prms[$px];
1645             $prm_clean =~ s/\[.*\]//;         !! 1629                         $prm_clean =~ s/\[.*\]//;
1646             $prm_clean =~ s/$attribute//i;    !! 1630                         $prm_clean =~ s/$attribute//i;
1647             # ignore array size in a paramete !! 1631                         # ignore array size in a parameter string;
1648             # however, the original param str !! 1632                         # however, the original param string may contain
1649             # spaces, e.g.:  addr[6 + 2]      !! 1633                         # spaces, e.g.:  addr[6 + 2]
1650             # and this appears in @prms as "a !! 1634                         # and this appears in @prms as "addr[6" since the
1651             # parameter list is split at spac !! 1635                         # parameter list is split at spaces;
1652             # hence just ignore "[..." for th !! 1636                         # hence just ignore "[..." for the sections check;
1653             $prm_clean =~ s/\[.*//;           !! 1637                         $prm_clean =~ s/\[.*//;
1654                                               !! 1638 
1655             ##$prm_clean =~ s/^\**//;         !! 1639                         ##$prm_clean =~ s/^\**//;
1656             if ($prm_clean eq $sects[$sx]) {  !! 1640                         if ($prm_clean eq $sects[$sx]) {
1657                 $err = 0;                     !! 1641                                 $err = 0;
1658                 last;                         !! 1642                                 last;
1659             }                                 !! 1643                         }
1660         }                                     !! 1644                 }
1661         if ($err) {                           !! 1645                 if ($err) {
1662             if ($decl_type eq "function") {   !! 1646                         if ($decl_type eq "function") {
1663                 emit_warning("${file}:$.",    !! 1647                                 emit_warning("${file}:$.",
1664                     "Excess function paramete !! 1648                                         "Excess function parameter " .
1665                     "'$sects[$sx]' " .        !! 1649                                         "'$sects[$sx]' " .
1666                     "description in '$decl_na !! 1650                                         "description in '$decl_name'\n");
1667             } elsif (($decl_type eq "struct") !! 1651                         }
1668                           ($decl_type eq "uni !! 1652                 }
1669                 emit_warning("${file}:$.",    !! 1653         }
1670                     "Excess $decl_type member << 
1671                     "'$sects[$sx]' " .        << 
1672                     "description in '$decl_na << 
1673             }                                 << 
1674         }                                     << 
1675     }                                         << 
1676 }                                                1654 }
1677                                                  1655 
1678 ##                                               1656 ##
1679 # Checks the section describing the return va    1657 # Checks the section describing the return value of a function.
1680 sub check_return_section {                       1658 sub check_return_section {
1681     my $file = shift;                         !! 1659         my $file = shift;
1682     my $declaration_name = shift;             !! 1660         my $declaration_name = shift;
1683     my $return_type = shift;                  !! 1661         my $return_type = shift;
1684                                               !! 1662 
1685     # Ignore an empty return type (It's a mac !! 1663         # Ignore an empty return type (It's a macro)
1686     # Ignore functions with a "void" return t !! 1664         # Ignore functions with a "void" return type. (But don't ignore "void *")
1687     if (($return_type eq "") || ($return_type !! 1665         if (($return_type eq "") || ($return_type =~ /void\s*\w*\s*$/)) {
1688         return;                               !! 1666                 return;
1689     }                                         !! 1667         }
1690                                                  1668 
1691     if (!defined($sections{$section_return})  !! 1669         if (!defined($sections{$section_return}) ||
1692         $sections{$section_return} eq "")     !! 1670             $sections{$section_return} eq "") {
1693     {                                         !! 1671                 emit_warning("${file}:$.",
1694         emit_warning("${file}:$.",            !! 1672                         "No description found for return value of " .
1695                      "No description found fo !! 1673                         "'$declaration_name'\n");
1696                      "'$declaration_name'\n") !! 1674         }
1697     }                                         << 
1698 }                                                1675 }
1699                                                  1676 
1700 ##                                               1677 ##
1701 # takes a function prototype and the name of     1678 # takes a function prototype and the name of the current file being
1702 # processed and spits out all the details sto    1679 # processed and spits out all the details stored in the global
1703 # arrays/hashes.                                 1680 # arrays/hashes.
1704 sub dump_function($$) {                          1681 sub dump_function($$) {
1705     my $prototype = shift;                       1682     my $prototype = shift;
1706     my $file = shift;                            1683     my $file = shift;
1707     my $noret = 0;                               1684     my $noret = 0;
1708                                                  1685 
1709     print_lineno($new_start_line);               1686     print_lineno($new_start_line);
1710                                                  1687 
1711     $prototype =~ s/^static +//;                 1688     $prototype =~ s/^static +//;
1712     $prototype =~ s/^extern +//;                 1689     $prototype =~ s/^extern +//;
1713     $prototype =~ s/^asmlinkage +//;             1690     $prototype =~ s/^asmlinkage +//;
1714     $prototype =~ s/^inline +//;                 1691     $prototype =~ s/^inline +//;
1715     $prototype =~ s/^__inline__ +//;             1692     $prototype =~ s/^__inline__ +//;
1716     $prototype =~ s/^__inline +//;               1693     $prototype =~ s/^__inline +//;
1717     $prototype =~ s/^__always_inline +//;        1694     $prototype =~ s/^__always_inline +//;
1718     $prototype =~ s/^noinline +//;               1695     $prototype =~ s/^noinline +//;
1719     $prototype =~ s/^__FORTIFY_INLINE +//;       1696     $prototype =~ s/^__FORTIFY_INLINE +//;
1720     $prototype =~ s/__init +//;                  1697     $prototype =~ s/__init +//;
1721     $prototype =~ s/__init_or_module +//;        1698     $prototype =~ s/__init_or_module +//;
1722     $prototype =~ s/__deprecated +//;            1699     $prototype =~ s/__deprecated +//;
1723     $prototype =~ s/__flatten +//;               1700     $prototype =~ s/__flatten +//;
1724     $prototype =~ s/__meminit +//;               1701     $prototype =~ s/__meminit +//;
1725     $prototype =~ s/__must_check +//;            1702     $prototype =~ s/__must_check +//;
1726     $prototype =~ s/__weak +//;                  1703     $prototype =~ s/__weak +//;
1727     $prototype =~ s/__sched +//;                 1704     $prototype =~ s/__sched +//;
1728     $prototype =~ s/_noprof//;                << 
1729     $prototype =~ s/__printf\s*\(\s*\d*\s*,\s    1705     $prototype =~ s/__printf\s*\(\s*\d*\s*,\s*\d*\s*\) +//;
1730     $prototype =~ s/__(?:re)?alloc_size\s*\(\    1706     $prototype =~ s/__(?:re)?alloc_size\s*\(\s*\d+\s*(?:,\s*\d+\s*)?\) +//;
1731     $prototype =~ s/__diagnose_as\s*\(\s*\S+\    1707     $prototype =~ s/__diagnose_as\s*\(\s*\S+\s*(?:,\s*\d+\s*)*\) +//;
1732     $prototype =~ s/DECL_BUCKET_PARAMS\s*\(\s << 
1733     my $define = $prototype =~ s/^#\s*define\    1708     my $define = $prototype =~ s/^#\s*define\s+//; #ak added
1734     $prototype =~ s/__attribute_const__ +//;     1709     $prototype =~ s/__attribute_const__ +//;
1735     $prototype =~ s/__attribute__\s*\(\(         1710     $prototype =~ s/__attribute__\s*\(\(
1736             (?:                                  1711             (?:
1737                  [\w\s]++          # attribut    1712                  [\w\s]++          # attribute name
1738                  (?:\([^)]*+\))?   # attribut    1713                  (?:\([^)]*+\))?   # attribute arguments
1739                  \s*+,?            # optional    1714                  \s*+,?            # optional comma at the end
1740             )+                                   1715             )+
1741           \)\)\s+//x;                            1716           \)\)\s+//x;
1742                                                  1717 
1743     # Yes, this truly is vile.  We are lookin    1718     # Yes, this truly is vile.  We are looking for:
1744     # 1. Return type (may be nothing if we're    1719     # 1. Return type (may be nothing if we're looking at a macro)
1745     # 2. Function name                           1720     # 2. Function name
1746     # 3. Function parameters.                    1721     # 3. Function parameters.
1747     #                                            1722     #
1748     # All the while we have to watch out for     1723     # All the while we have to watch out for function pointer parameters
1749     # (which IIRC is what the two sections ar    1724     # (which IIRC is what the two sections are for), C types (these
1750     # regexps don't even start to express all    1725     # regexps don't even start to express all the possibilities), and
1751     # so on.                                     1726     # so on.
1752     #                                            1727     #
1753     # If you mess with these regexps, it's a     1728     # If you mess with these regexps, it's a good idea to check that
1754     # the following functions' documentation     1729     # the following functions' documentation still comes out right:
1755     # - parport_register_device (function poi    1730     # - parport_register_device (function pointer parameters)
1756     # - atomic_set (macro)                       1731     # - atomic_set (macro)
1757     # - pci_match_device, __copy_to_user (lon    1732     # - pci_match_device, __copy_to_user (long return type)
1758     my $name = qr{[a-zA-Z0-9_~:]+};              1733     my $name = qr{[a-zA-Z0-9_~:]+};
1759     my $prototype_end1 = qr{[^\(]*};             1734     my $prototype_end1 = qr{[^\(]*};
1760     my $prototype_end2 = qr{[^\{]*};             1735     my $prototype_end2 = qr{[^\{]*};
1761     my $prototype_end = qr{\(($prototype_end1    1736     my $prototype_end = qr{\(($prototype_end1|$prototype_end2)\)};
1762     my $type1 = qr{[\w\s]+};                     1737     my $type1 = qr{[\w\s]+};
1763     my $type2 = qr{$type1\*+};                   1738     my $type2 = qr{$type1\*+};
1764                                                  1739 
1765     if ($define && $prototype =~ m/^()($name)    1740     if ($define && $prototype =~ m/^()($name)\s+/) {
1766         # This is an object-like macro, it ha    1741         # This is an object-like macro, it has no return type and no parameter
1767         # list.                                  1742         # list.
1768         # Function-like macros are not allowe    1743         # Function-like macros are not allowed to have spaces between
1769         # declaration_name and opening parent    1744         # declaration_name and opening parenthesis (notice the \s+).
1770         $return_type = $1;                       1745         $return_type = $1;
1771         $declaration_name = $2;                  1746         $declaration_name = $2;
1772         $noret = 1;                              1747         $noret = 1;
1773     } elsif ($prototype =~ m/^()($name)\s*$pr    1748     } elsif ($prototype =~ m/^()($name)\s*$prototype_end/ ||
1774         $prototype =~ m/^($type1)\s+($name)\s !! 1749         $prototype =~ m/^($type1)\s+($name)\s*$prototype_end/ ||
1775         $prototype =~ m/^($type2+)\s*($name)\ !! 1750         $prototype =~ m/^($type2+)\s*($name)\s*$prototype_end/)  {
1776         $return_type = $1;                    !! 1751         $return_type = $1;
1777         $declaration_name = $2;               !! 1752         $declaration_name = $2;
1778         my $args = $3;                        !! 1753         my $args = $3;
1779                                                  1754 
1780         create_parameterlist($args, ',', $fil !! 1755         create_parameterlist($args, ',', $file, $declaration_name);
1781     } else {                                     1756     } else {
1782         emit_warning("${file}:$.", "cannot un !! 1757         emit_warning("${file}:$.", "cannot understand function prototype: '$prototype'\n");
1783         return;                               !! 1758         return;
1784     }                                            1759     }
1785                                                  1760 
1786     if ($identifier ne $declaration_name) {      1761     if ($identifier ne $declaration_name) {
1787         emit_warning("${file}:$.", "expecting !! 1762         emit_warning("${file}:$.", "expecting prototype for $identifier(). Prototype was for $declaration_name() instead\n");
1788         return;                               !! 1763         return;
1789     }                                            1764     }
1790                                                  1765 
1791     my $prms = join " ", @parameterlist;         1766     my $prms = join " ", @parameterlist;
1792     check_sections($file, $declaration_name,     1767     check_sections($file, $declaration_name, "function", $sectcheck, $prms);
1793                                                  1768 
1794     # This check emits a lot of warnings at t    1769     # This check emits a lot of warnings at the moment, because many
1795     # functions don't have a 'Return' doc sec    1770     # functions don't have a 'Return' doc section. So until the number
1796     # of warnings goes sufficiently down, the    1771     # of warnings goes sufficiently down, the check is only performed in
1797     # -Wreturn mode.                             1772     # -Wreturn mode.
1798     # TODO: always perform the check.            1773     # TODO: always perform the check.
1799     if ($Wreturn && !$noret) {                   1774     if ($Wreturn && !$noret) {
1800         check_return_section($file, $declarat !! 1775             check_return_section($file, $declaration_name, $return_type);
1801     }                                            1776     }
1802                                                  1777 
1803     # The function parser can be called with     1778     # The function parser can be called with a typedef parameter.
1804     # Handle it.                                 1779     # Handle it.
1805     if ($return_type =~ /typedef/) {             1780     if ($return_type =~ /typedef/) {
1806         output_declaration($declaration_name, !! 1781         output_declaration($declaration_name,
1807                            'function',        !! 1782                            'function',
1808                            {'function' => $de !! 1783                            {'function' => $declaration_name,
1809                             'typedef' => 1,   !! 1784                             'typedef' => 1,
1810                             'module' => $modu !! 1785                             'module' => $modulename,
1811                             'functiontype' => !! 1786                             'functiontype' => $return_type,
1812                             'parameterlist' = !! 1787                             'parameterlist' => \@parameterlist,
1813                             'parameterdescs'  !! 1788                             'parameterdescs' => \%parameterdescs,
1814                             'parametertypes'  !! 1789                             'parametertypes' => \%parametertypes,
1815                             'sectionlist' =>  !! 1790                             'sectionlist' => \@sectionlist,
1816                             'sections' => \%s !! 1791                             'sections' => \%sections,
1817                             'purpose' => $dec !! 1792                             'purpose' => $declaration_purpose
1818                            });                !! 1793                            });
1819     } else {                                     1794     } else {
1820         output_declaration($declaration_name, !! 1795         output_declaration($declaration_name,
1821                            'function',        !! 1796                            'function',
1822                            {'function' => $de !! 1797                            {'function' => $declaration_name,
1823                             'module' => $modu !! 1798                             'module' => $modulename,
1824                             'functiontype' => !! 1799                             'functiontype' => $return_type,
1825                             'parameterlist' = !! 1800                             'parameterlist' => \@parameterlist,
1826                             'parameterdescs'  !! 1801                             'parameterdescs' => \%parameterdescs,
1827                             'parametertypes'  !! 1802                             'parametertypes' => \%parametertypes,
1828                             'sectionlist' =>  !! 1803                             'sectionlist' => \@sectionlist,
1829                             'sections' => \%s !! 1804                             'sections' => \%sections,
1830                             'purpose' => $dec !! 1805                             'purpose' => $declaration_purpose
1831                            });                !! 1806                            });
1832     }                                            1807     }
1833 }                                                1808 }
1834                                                  1809 
1835 sub reset_state {                                1810 sub reset_state {
1836     $function = "";                              1811     $function = "";
1837     %parameterdescs = ();                        1812     %parameterdescs = ();
1838     %parametertypes = ();                        1813     %parametertypes = ();
1839     @parameterlist = ();                         1814     @parameterlist = ();
1840     %sections = ();                              1815     %sections = ();
1841     @sectionlist = ();                           1816     @sectionlist = ();
1842     $sectcheck = "";                             1817     $sectcheck = "";
1843     $struct_actual = "";                         1818     $struct_actual = "";
1844     $prototype = "";                             1819     $prototype = "";
1845                                                  1820 
1846     $state = STATE_NORMAL;                       1821     $state = STATE_NORMAL;
1847     $inline_doc_state = STATE_INLINE_NA;         1822     $inline_doc_state = STATE_INLINE_NA;
1848 }                                                1823 }
1849                                                  1824 
1850 sub tracepoint_munge($) {                        1825 sub tracepoint_munge($) {
1851     my $file = shift;                         !! 1826         my $file = shift;
1852     my $tracepointname = 0;                   !! 1827         my $tracepointname = 0;
1853     my $tracepointargs = 0;                   !! 1828         my $tracepointargs = 0;
1854                                               !! 1829 
1855     if ($prototype =~ m/TRACE_EVENT\((.*?),/) !! 1830         if ($prototype =~ m/TRACE_EVENT\((.*?),/) {
1856         $tracepointname = $1;                 !! 1831                 $tracepointname = $1;
1857     }                                         !! 1832         }
1858     if ($prototype =~ m/DEFINE_SINGLE_EVENT\( !! 1833         if ($prototype =~ m/DEFINE_SINGLE_EVENT\((.*?),/) {
1859         $tracepointname = $1;                 !! 1834                 $tracepointname = $1;
1860     }                                         !! 1835         }
1861     if ($prototype =~ m/DEFINE_EVENT\((.*?),( !! 1836         if ($prototype =~ m/DEFINE_EVENT\((.*?),(.*?),/) {
1862         $tracepointname = $2;                 !! 1837                 $tracepointname = $2;
1863     }                                         !! 1838         }
1864     $tracepointname =~ s/^\s+//; #strip leadi !! 1839         $tracepointname =~ s/^\s+//; #strip leading whitespace
1865     if ($prototype =~ m/TP_PROTO\((.*?)\)/) { !! 1840         if ($prototype =~ m/TP_PROTO\((.*?)\)/) {
1866         $tracepointargs = $1;                 !! 1841                 $tracepointargs = $1;
1867     }                                         !! 1842         }
1868     if (($tracepointname eq 0) || ($tracepoin !! 1843         if (($tracepointname eq 0) || ($tracepointargs eq 0)) {
1869         emit_warning("${file}:$.", "Unrecogni !! 1844                 emit_warning("${file}:$.", "Unrecognized tracepoint format: \n".
1870                  "$prototype\n");             !! 1845                              "$prototype\n");
1871     } else {                                  !! 1846         } else {
1872         $prototype = "static inline void trac !! 1847                 $prototype = "static inline void trace_$tracepointname($tracepointargs)";
1873         $identifier = "trace_$identifier";    !! 1848                 $identifier = "trace_$identifier";
1874     }                                         !! 1849         }
1875 }                                                1850 }
1876                                                  1851 
1877 sub syscall_munge() {                            1852 sub syscall_munge() {
1878     my $void = 0;                             !! 1853         my $void = 0;
1879                                                  1854 
1880     $prototype =~ s@[\r\n]+@ @gos; # strip ne !! 1855         $prototype =~ s@[\r\n]+@ @gos; # strip newlines/CR's
1881 ##    if ($prototype =~ m/SYSCALL_DEFINE0\s*\ !! 1856 ##      if ($prototype =~ m/SYSCALL_DEFINE0\s*\(\s*(a-zA-Z0-9_)*\s*\)/) {
1882     if ($prototype =~ m/SYSCALL_DEFINE0/) {   !! 1857         if ($prototype =~ m/SYSCALL_DEFINE0/) {
1883         $void = 1;                            !! 1858                 $void = 1;
1884 ##        $prototype = "long sys_$1(void)";   !! 1859 ##              $prototype = "long sys_$1(void)";
1885     }                                         !! 1860         }
1886                                               !! 1861 
1887     $prototype =~ s/SYSCALL_DEFINE.*\(/long s !! 1862         $prototype =~ s/SYSCALL_DEFINE.*\(/long sys_/; # fix return type & func name
1888     if ($prototype =~ m/long (sys_.*?),/) {   !! 1863         if ($prototype =~ m/long (sys_.*?),/) {
1889         $prototype =~ s/,/\(/;                !! 1864                 $prototype =~ s/,/\(/;
1890     } elsif ($void) {                         !! 1865         } elsif ($void) {
1891         $prototype =~ s/\)/\(void\)/;         !! 1866                 $prototype =~ s/\)/\(void\)/;
1892     }                                         !! 1867         }
1893                                               !! 1868 
1894     # now delete all of the odd-number commas !! 1869         # now delete all of the odd-number commas in $prototype
1895     # so that arg types & arg names don't hav !! 1870         # so that arg types & arg names don't have a comma between them
1896     my $count = 0;                            !! 1871         my $count = 0;
1897     my $len = length($prototype);             !! 1872         my $len = length($prototype);
1898     if ($void) {                              !! 1873         if ($void) {
1899         $len = 0;    # skip the for-loop      !! 1874                 $len = 0;       # skip the for-loop
1900     }                                         !! 1875         }
1901     for (my $ix = 0; $ix < $len; $ix++) {     !! 1876         for (my $ix = 0; $ix < $len; $ix++) {
1902         if (substr($prototype, $ix, 1) eq ',' !! 1877                 if (substr($prototype, $ix, 1) eq ',') {
1903             $count++;                         !! 1878                         $count++;
1904             if ($count % 2 == 1) {            !! 1879                         if ($count % 2 == 1) {
1905                 substr($prototype, $ix, 1) =  !! 1880                                 substr($prototype, $ix, 1) = ' ';
1906             }                                 !! 1881                         }
1907         }                                     !! 1882                 }
1908     }                                         !! 1883         }
1909 }                                                1884 }
1910                                                  1885 
1911 sub process_proto_function($$) {                 1886 sub process_proto_function($$) {
1912     my $x = shift;                               1887     my $x = shift;
1913     my $file = shift;                            1888     my $file = shift;
1914                                                  1889 
1915     $x =~ s@\/\/.*$@@gos; # strip C99-style c    1890     $x =~ s@\/\/.*$@@gos; # strip C99-style comments to end of line
1916                                                  1891 
1917     if ($x =~ /^#/ && $x !~ /^#\s*define/) {  !! 1892     if ($x =~ m#\s*/\*\s+MACDOC\s*#io || ($x =~ /^#/ && $x !~ /^#\s*define/)) {
1918         # do nothing                          !! 1893         # do nothing
1919     } elsif ($x =~ /([^\{]*)/) {              !! 1894     }
1920         $prototype .= $1;                     !! 1895     elsif ($x =~ /([^\{]*)/) {
                                                   >> 1896         $prototype .= $1;
1921     }                                            1897     }
1922                                                  1898 
1923     if (($x =~ /\{/) || ($x =~ /\#\s*define/)    1899     if (($x =~ /\{/) || ($x =~ /\#\s*define/) || ($x =~ /;/)) {
1924         $prototype =~ s@/\*.*?\*/@@gos;       !! 1900         $prototype =~ s@/\*.*?\*/@@gos; # strip comments.
1925         $prototype =~ s@[\r\n]+@ @gos; # stri !! 1901         $prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
1926         $prototype =~ s@^\s+@@gos; # strip le !! 1902         $prototype =~ s@^\s+@@gos; # strip leading spaces
1927                                               !! 1903 
1928         # Handle prototypes for function poin !! 1904          # Handle prototypes for function pointers like:
1929         # int (*pcs_config)(struct foo)       !! 1905          # int (*pcs_config)(struct foo)
1930         $prototype =~ s@^(\S+\s+)\(\s*\*(\S+) !! 1906         $prototype =~ s@^(\S+\s+)\(\s*\*(\S+)\)@$1$2@gos;
1931                                               !! 1907 
1932         if ($prototype =~ /SYSCALL_DEFINE/) { !! 1908         if ($prototype =~ /SYSCALL_DEFINE/) {
1933             syscall_munge();                  !! 1909                 syscall_munge();
1934         }                                     !! 1910         }
1935         if ($prototype =~ /TRACE_EVENT/ || $p !! 1911         if ($prototype =~ /TRACE_EVENT/ || $prototype =~ /DEFINE_EVENT/ ||
1936             $prototype =~ /DEFINE_SINGLE_EVEN !! 1912             $prototype =~ /DEFINE_SINGLE_EVENT/)
1937         {                                     !! 1913         {
1938             tracepoint_munge($file);          !! 1914                 tracepoint_munge($file);
1939         }                                     !! 1915         }
1940         dump_function($prototype, $file);     !! 1916         dump_function($prototype, $file);
1941         reset_state();                        !! 1917         reset_state();
1942     }                                            1918     }
1943 }                                                1919 }
1944                                                  1920 
1945 sub process_proto_type($$) {                     1921 sub process_proto_type($$) {
1946     my $x = shift;                               1922     my $x = shift;
1947     my $file = shift;                            1923     my $file = shift;
1948                                                  1924 
1949     $x =~ s@[\r\n]+@ @gos; # strip newlines/c    1925     $x =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
1950     $x =~ s@^\s+@@gos; # strip leading spaces    1926     $x =~ s@^\s+@@gos; # strip leading spaces
1951     $x =~ s@\s+$@@gos; # strip trailing space    1927     $x =~ s@\s+$@@gos; # strip trailing spaces
1952     $x =~ s@\/\/.*$@@gos; # strip C99-style c    1928     $x =~ s@\/\/.*$@@gos; # strip C99-style comments to end of line
1953                                                  1929 
1954     if ($x =~ /^#/) {                            1930     if ($x =~ /^#/) {
1955         # To distinguish preprocessor directi !! 1931         # To distinguish preprocessor directive from regular declaration later.
1956         $x .= ";";                            !! 1932         $x .= ";";
1957     }                                            1933     }
1958                                                  1934 
1959     while (1) {                                  1935     while (1) {
1960         if ( $x =~ /([^\{\};]*)([\{\};])(.*)/ !! 1936         if ( $x =~ /([^\{\};]*)([\{\};])(.*)/ ) {
1961             if( length $prototype ) {            1937             if( length $prototype ) {
1962                 $prototype .= " "                1938                 $prototype .= " "
1963             }                                    1939             }
1964             $prototype .= $1 . $2;            !! 1940             $prototype .= $1 . $2;
1965             ($2 eq '{') && $brcount++;        !! 1941             ($2 eq '{') && $brcount++;
1966             ($2 eq '}') && $brcount--;        !! 1942             ($2 eq '}') && $brcount--;
1967             if (($2 eq ';') && ($brcount == 0 !! 1943             if (($2 eq ';') && ($brcount == 0)) {
1968                 dump_declaration($prototype,  !! 1944                 dump_declaration($prototype, $file);
1969                 reset_state();                !! 1945                 reset_state();
1970                 last;                         !! 1946                 last;
1971             }                                 !! 1947             }
1972             $x = $3;                          !! 1948             $x = $3;
1973         } else {                              !! 1949         } else {
1974             $prototype .= $x;                 !! 1950             $prototype .= $x;
1975             last;                             !! 1951             last;
1976         }                                     !! 1952         }
1977     }                                            1953     }
1978 }                                                1954 }
1979                                                  1955 
1980                                                  1956 
1981 sub map_filename($) {                            1957 sub map_filename($) {
1982     my $file;                                    1958     my $file;
1983     my ($orig_file) = @_;                        1959     my ($orig_file) = @_;
1984                                                  1960 
1985     if (defined($ENV{'SRCTREE'})) {              1961     if (defined($ENV{'SRCTREE'})) {
1986         $file = "$ENV{'SRCTREE'}" . "/" . $or !! 1962         $file = "$ENV{'SRCTREE'}" . "/" . $orig_file;
1987     } else {                                     1963     } else {
1988         $file = $orig_file;                   !! 1964         $file = $orig_file;
1989     }                                            1965     }
1990                                                  1966 
1991     if (defined($source_map{$file})) {           1967     if (defined($source_map{$file})) {
1992         $file = $source_map{$file};           !! 1968         $file = $source_map{$file};
1993     }                                            1969     }
1994                                                  1970 
1995     return $file;                                1971     return $file;
1996 }                                                1972 }
1997                                                  1973 
1998 sub process_export_file($) {                     1974 sub process_export_file($) {
1999     my ($orig_file) = @_;                        1975     my ($orig_file) = @_;
2000     my $file = map_filename($orig_file);         1976     my $file = map_filename($orig_file);
2001                                                  1977 
2002     if (!open(IN,"<$file")) {                    1978     if (!open(IN,"<$file")) {
2003         print STDERR "Error: Cannot open file !! 1979         print STDERR "Error: Cannot open file $file\n";
2004         ++$errors;                            !! 1980         ++$errors;
2005         return;                               !! 1981         return;
2006     }                                            1982     }
2007                                                  1983 
2008     while (<IN>) {                               1984     while (<IN>) {
2009         if (/$export_symbol/) {               !! 1985         if (/$export_symbol/) {
2010             next if (defined($nosymbol_table{ !! 1986             next if (defined($nosymbol_table{$2}));
2011             $function_table{$2} = 1;          !! 1987             $function_table{$2} = 1;
2012         }                                     !! 1988         }
2013         if (/$export_symbol_ns/) {            !! 1989         if (/$export_symbol_ns/) {
2014             next if (defined($nosymbol_table{ !! 1990             next if (defined($nosymbol_table{$2}));
2015             $function_table{$2} = 1;          !! 1991             $function_table{$2} = 1;
2016         }                                     !! 1992         }
2017     }                                            1993     }
2018                                                  1994 
2019     close(IN);                                   1995     close(IN);
2020 }                                                1996 }
2021                                                  1997 
2022 #                                                1998 #
2023 # Parsers for the various processing states.     1999 # Parsers for the various processing states.
2024 #                                                2000 #
2025 # STATE_NORMAL: looking for the /** to begin     2001 # STATE_NORMAL: looking for the /** to begin everything.
2026 #                                                2002 #
2027 sub process_normal() {                           2003 sub process_normal() {
2028     if (/$doc_start/o) {                         2004     if (/$doc_start/o) {
2029         $state = STATE_NAME;        # next li !! 2005         $state = STATE_NAME;    # next line is always the function name
2030         $in_doc_sect = 0;                     !! 2006         $in_doc_sect = 0;
2031         $declaration_start_line = $. + 1;     !! 2007         $declaration_start_line = $. + 1;
2032     }                                            2008     }
2033 }                                                2009 }
2034                                                  2010 
2035 #                                                2011 #
2036 # STATE_NAME: Looking for the "name - descrip    2012 # STATE_NAME: Looking for the "name - description" line
2037 #                                                2013 #
2038 sub process_name($$) {                           2014 sub process_name($$) {
2039     my $file = shift;                            2015     my $file = shift;
2040     my $descr;                                   2016     my $descr;
2041                                                  2017 
2042     if (/$doc_block/o) {                         2018     if (/$doc_block/o) {
2043         $state = STATE_DOCBLOCK;              !! 2019         $state = STATE_DOCBLOCK;
2044         $contents = "";                       !! 2020         $contents = "";
2045         $new_start_line = $.;                 !! 2021         $new_start_line = $.;
2046                                               !! 2022 
2047         if ( $1 eq "" ) {                     !! 2023         if ( $1 eq "" ) {
2048             $section = $section_intro;        !! 2024             $section = $section_intro;
2049         } else {                              !! 2025         } else {
2050             $section = $1;                    !! 2026             $section = $1;
2051         }                                     !! 2027         }
2052     } elsif (/$doc_decl/o) {                     2028     } elsif (/$doc_decl/o) {
2053         $identifier = $1;                     !! 2029         $identifier = $1;
2054         my $is_kernel_comment = 0;            !! 2030         my $is_kernel_comment = 0;
2055         my $decl_start = qr{$doc_com};        !! 2031         my $decl_start = qr{$doc_com};
2056         # test for pointer declaration type,  !! 2032         # test for pointer declaration type, foo * bar() - desc
2057         my $fn_type = qr{\w+\s*\*\s*};        !! 2033         my $fn_type = qr{\w+\s*\*\s*}; 
2058         my $parenthesis = qr{\(\w*\)};        !! 2034         my $parenthesis = qr{\(\w*\)};
2059         my $decl_end = qr{[-:].*};            !! 2035         my $decl_end = qr{[-:].*};
2060         if (/^$decl_start([\w\s]+?)$parenthes !! 2036         if (/^$decl_start([\w\s]+?)$parenthesis?\s*$decl_end?$/) {
2061             $identifier = $1;                 !! 2037             $identifier = $1;
2062         }                                     !! 2038         }
2063         if ($identifier =~ m/^(struct|union|e !! 2039         if ($identifier =~ m/^(struct|union|enum|typedef)\b\s*(\S*)/) {
2064             $decl_type = $1;                  !! 2040             $decl_type = $1;
2065             $identifier = $2;                 !! 2041             $identifier = $2;
2066             $is_kernel_comment = 1;           !! 2042             $is_kernel_comment = 1;
2067         }                                     !! 2043         }
2068         # Look for foo() or static void foo() !! 2044         # Look for foo() or static void foo() - description; or misspelt
2069         # identifier                          !! 2045         # identifier
2070         elsif (/^$decl_start$fn_type?(\w+)\s* !! 2046         elsif (/^$decl_start$fn_type?(\w+)\s*$parenthesis?\s*$decl_end?$/ ||
2071             /^$decl_start$fn_type?(\w+.*)$par !! 2047             /^$decl_start$fn_type?(\w+.*)$parenthesis?\s*$decl_end$/) {
2072             $identifier = $1;                 !! 2048             $identifier = $1;
2073             $decl_type = 'function';          !! 2049             $decl_type = 'function';
2074             $identifier =~ s/^define\s+//;    !! 2050             $identifier =~ s/^define\s+//;
2075             $is_kernel_comment = 1;           !! 2051             $is_kernel_comment = 1;
2076         }                                     !! 2052         }
2077         $identifier =~ s/\s+$//;              !! 2053         $identifier =~ s/\s+$//;
2078                                               !! 2054 
2079         $state = STATE_BODY;                  !! 2055         $state = STATE_BODY;
2080         # if there's no @param blocks need to !! 2056         # if there's no @param blocks need to set up default section
2081         # here                                !! 2057         # here
2082         $contents = "";                       !! 2058         $contents = "";
2083         $section = $section_default;          !! 2059         $section = $section_default;
2084         $new_start_line = $. + 1;             !! 2060         $new_start_line = $. + 1;
2085         if (/[-:](.*)/) {                     !! 2061         if (/[-:](.*)/) {
2086             # strip leading/trailing/multiple !! 2062             # strip leading/trailing/multiple spaces
2087             $descr= $1;                       !! 2063             $descr= $1;
2088             $descr =~ s/^\s*//;               !! 2064             $descr =~ s/^\s*//;
2089             $descr =~ s/\s*$//;               !! 2065             $descr =~ s/\s*$//;
2090             $descr =~ s/\s+/ /g;              !! 2066             $descr =~ s/\s+/ /g;
2091             $declaration_purpose = $descr;    !! 2067             $declaration_purpose = $descr;
2092             $state = STATE_BODY_MAYBE;        !! 2068             $state = STATE_BODY_MAYBE;
2093         } else {                              !! 2069         } else {
2094             $declaration_purpose = "";        !! 2070             $declaration_purpose = "";
2095         }                                     !! 2071         }
2096                                               !! 2072 
2097         if (!$is_kernel_comment) {            !! 2073         if (!$is_kernel_comment) {
2098             emit_warning("${file}:$.", "This  !! 2074             emit_warning("${file}:$.", "This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst\n$_");
2099             $state = STATE_NORMAL;            !! 2075             $state = STATE_NORMAL;
2100         }                                     !! 2076         }
2101                                               !! 2077 
2102         if (($declaration_purpose eq "") && $ !! 2078         if (($declaration_purpose eq "") && $Wshort_desc) {
2103             emit_warning("${file}:$.", "missi !! 2079             emit_warning("${file}:$.", "missing initial short description on line:\n$_");
2104         }                                     !! 2080         }
2105                                               !! 2081 
2106         if ($identifier eq "" && $decl_type n !! 2082         if ($identifier eq "" && $decl_type ne "enum") {
2107             emit_warning("${file}:$.", "wrong !! 2083             emit_warning("${file}:$.", "wrong kernel-doc identifier on line:\n$_");
2108             $state = STATE_NORMAL;            !! 2084             $state = STATE_NORMAL;
2109         }                                     !! 2085         }
2110                                               !! 2086 
2111         if ($verbose) {                       !! 2087         if ($verbose) {
2112             print STDERR "${file}:$.: info: S !! 2088             print STDERR "${file}:$.: info: Scanning doc for $decl_type $identifier\n";
2113         }                                     !! 2089         }
2114     } else {                                     2090     } else {
2115         emit_warning("${file}:$.", "Cannot un !! 2091         emit_warning("${file}:$.", "Cannot understand $_ on line $. - I thought it was a doc line\n");
2116         $state = STATE_NORMAL;                !! 2092         $state = STATE_NORMAL;
2117     }                                            2093     }
2118 }                                                2094 }
2119                                                  2095 
2120                                                  2096 
2121 #                                                2097 #
2122 # STATE_BODY and STATE_BODY_MAYBE: the bulk o    2098 # STATE_BODY and STATE_BODY_MAYBE: the bulk of a kerneldoc comment.
2123 #                                                2099 #
2124 sub process_body($$) {                           2100 sub process_body($$) {
2125     my $file = shift;                            2101     my $file = shift;
2126                                                  2102 
2127     if ($state == STATE_BODY_WITH_BLANK_LINE     2103     if ($state == STATE_BODY_WITH_BLANK_LINE && /^\s*\*\s?\S/) {
2128         dump_section($file, $section, $conten !! 2104         dump_section($file, $section, $contents);
2129         $section = $section_default;          !! 2105         $section = $section_default;
2130         $new_start_line = $.;                 !! 2106         $new_start_line = $.;
2131         $contents = "";                       !! 2107         $contents = "";
2132     }                                            2108     }
2133                                                  2109 
2134     if (/$doc_sect/i) { # case insensitive fo    2110     if (/$doc_sect/i) { # case insensitive for supported section names
2135         $in_doc_sect = 1;                     !! 2111         $newsection = $1;
2136         $newsection = $1;                     !! 2112         $newcontents = $2;
2137         $newcontents = $2;                    << 
2138                                               << 
2139         # map the supported section names to  << 
2140         if ($newsection =~ m/^description$/i) << 
2141             $newsection = $section_default;   << 
2142         } elsif ($newsection =~ m/^context$/i << 
2143             $newsection = $section_context;   << 
2144         } elsif ($newsection =~ m/^returns?$/ << 
2145             $newsection = $section_return;    << 
2146         } elsif ($newsection =~ m/^\@return$/ << 
2147             # special: @return is a section,  << 
2148             $newsection = $section_return;    << 
2149         }                                     << 
2150                                                  2113 
2151         if (($contents ne "") && ($contents n !! 2114         # map the supported section names to the canonical names
2152             if (!$in_doc_sect && $Wcontents_b !! 2115         if ($newsection =~ m/^description$/i) {
2153                 emit_warning("${file}:$.", "c !! 2116             $newsection = $section_default;
2154             }                                 !! 2117         } elsif ($newsection =~ m/^context$/i) {
2155             dump_section($file, $section, $co !! 2118             $newsection = $section_context;
2156             $section = $section_default;      !! 2119         } elsif ($newsection =~ m/^returns?$/i) {
2157         }                                     !! 2120             $newsection = $section_return;
2158                                               !! 2121         } elsif ($newsection =~ m/^\@return$/) {
2159         $in_doc_sect = 1;                     !! 2122             # special: @return is a section, not a param description
2160         $state = STATE_BODY;                  !! 2123             $newsection = $section_return;
2161         $contents = $newcontents;             !! 2124         }
2162         $new_start_line = $.;                 !! 2125 
2163         while (substr($contents, 0, 1) eq " " !! 2126         if (($contents ne "") && ($contents ne "\n")) {
2164             $contents = substr($contents, 1); !! 2127             if (!$in_doc_sect && $Wcontents_before_sections) {
2165         }                                     !! 2128                 emit_warning("${file}:$.", "contents before sections\n");
2166         if ($contents ne "") {                !! 2129             }
2167             $contents .= "\n";                !! 2130             dump_section($file, $section, $contents);
2168         }                                     !! 2131             $section = $section_default;
2169         $section = $newsection;               !! 2132         }
2170         $leading_space = undef;               !! 2133 
                                                   >> 2134         $in_doc_sect = 1;
                                                   >> 2135         $state = STATE_BODY;
                                                   >> 2136         $contents = $newcontents;
                                                   >> 2137         $new_start_line = $.;
                                                   >> 2138         while (substr($contents, 0, 1) eq " ") {
                                                   >> 2139             $contents = substr($contents, 1);
                                                   >> 2140         }
                                                   >> 2141         if ($contents ne "") {
                                                   >> 2142             $contents .= "\n";
                                                   >> 2143         }
                                                   >> 2144         $section = $newsection;
                                                   >> 2145         $leading_space = undef;
2171     } elsif (/$doc_end/) {                       2146     } elsif (/$doc_end/) {
2172         if (($contents ne "") && ($contents n !! 2147         if (($contents ne "") && ($contents ne "\n")) {
2173             dump_section($file, $section, $co !! 2148             dump_section($file, $section, $contents);
2174             $section = $section_default;      !! 2149             $section = $section_default;
2175             $contents = "";                   !! 2150             $contents = "";
2176         }                                     !! 2151         }
2177         # look for doc_com + <text> + doc_end !! 2152         # look for doc_com + <text> + doc_end:
2178         if ($_ =~ m'\s*\*\s*[a-zA-Z_0-9:\.]+\ !! 2153         if ($_ =~ m'\s*\*\s*[a-zA-Z_0-9:\.]+\*/') {
2179             emit_warning("${file}:$.", "suspi !! 2154             emit_warning("${file}:$.", "suspicious ending line: $_");
2180         }                                     !! 2155         }
2181                                               !! 2156 
2182         $prototype = "";                      !! 2157         $prototype = "";
2183         $state = STATE_PROTO;                 !! 2158         $state = STATE_PROTO;
2184         $brcount = 0;                         !! 2159         $brcount = 0;
2185         $new_start_line = $. + 1;                2160         $new_start_line = $. + 1;
2186     } elsif (/$doc_content/) {                   2161     } elsif (/$doc_content/) {
2187         if ($1 eq "") {                       !! 2162         if ($1 eq "") {
2188             if ($section eq $section_context) !! 2163             if ($section eq $section_context) {
2189                 dump_section($file, $section, !! 2164                 dump_section($file, $section, $contents);
2190                 $section = $section_default;  !! 2165                 $section = $section_default;
2191                 $contents = "";               !! 2166                 $contents = "";
2192                 $new_start_line = $.;         !! 2167                 $new_start_line = $.;
2193                 $state = STATE_BODY;          !! 2168                 $state = STATE_BODY;
2194             } else {                          !! 2169             } else {
2195                 if ($section ne $section_defa !! 2170                 if ($section ne $section_default) {
2196                     $state = STATE_BODY_WITH_ !! 2171                     $state = STATE_BODY_WITH_BLANK_LINE;
2197                 } else {                      !! 2172                 } else {
2198                     $state = STATE_BODY;      !! 2173                     $state = STATE_BODY;
2199                 }                             !! 2174                 }
2200                 $contents .= "\n";            !! 2175                 $contents .= "\n";
2201             }                                 !! 2176             }
2202         } elsif ($state == STATE_BODY_MAYBE)  !! 2177         } elsif ($state == STATE_BODY_MAYBE) {
2203             # Continued declaration purpose   !! 2178             # Continued declaration purpose
2204             chomp($declaration_purpose);      !! 2179             chomp($declaration_purpose);
2205             $declaration_purpose .= " " . $1; !! 2180             $declaration_purpose .= " " . $1;
2206             $declaration_purpose =~ s/\s+/ /g !! 2181             $declaration_purpose =~ s/\s+/ /g;
2207         } else {                              !! 2182         } else {
2208             my $cont = $1;                    !! 2183             my $cont = $1;
2209             if ($section =~ m/^@/ || $section !! 2184             if ($section =~ m/^@/ || $section eq $section_context) {
2210                 if (!defined $leading_space)  !! 2185                 if (!defined $leading_space) {
2211                     if ($cont =~ m/^(\s+)/) { !! 2186                     if ($cont =~ m/^(\s+)/) {
2212                         $leading_space = $1;  !! 2187                         $leading_space = $1;
2213                     } else {                  !! 2188                     } else {
2214                         $leading_space = "";  !! 2189                         $leading_space = "";
2215                     }                         !! 2190                     }
2216                 }                             !! 2191                 }
2217                 $cont =~ s/^$leading_space//; !! 2192                 $cont =~ s/^$leading_space//;
2218             }                                 !! 2193             }
2219             $contents .= $cont . "\n";        !! 2194             $contents .= $cont . "\n";
2220         }                                     !! 2195         }
2221     } else {                                     2196     } else {
2222         # i dont know - bad line?  ignore.    !! 2197         # i dont know - bad line?  ignore.
2223         emit_warning("${file}:$.", "bad line: !! 2198         emit_warning("${file}:$.", "bad line: $_");
2224     }                                            2199     }
2225 }                                                2200 }
2226                                                  2201 
2227                                                  2202 
2228 #                                                2203 #
2229 # STATE_PROTO: reading a function/whatever pr    2204 # STATE_PROTO: reading a function/whatever prototype.
2230 #                                                2205 #
2231 sub process_proto($$) {                          2206 sub process_proto($$) {
2232     my $file = shift;                            2207     my $file = shift;
2233                                                  2208 
2234     if (/$doc_inline_oneline/) {                 2209     if (/$doc_inline_oneline/) {
2235         $section = $1;                        !! 2210         $section = $1;
2236         $contents = $2;                       !! 2211         $contents = $2;
2237         if ($contents ne "") {                !! 2212         if ($contents ne "") {
2238             $contents .= "\n";                !! 2213             $contents .= "\n";
2239             dump_section($file, $section, $co !! 2214             dump_section($file, $section, $contents);
2240             $section = $section_default;      !! 2215             $section = $section_default;
2241             $contents = "";                   !! 2216             $contents = "";
2242         }                                     !! 2217         }
2243     } elsif (/$doc_inline_start/) {              2218     } elsif (/$doc_inline_start/) {
2244         $state = STATE_INLINE;                !! 2219         $state = STATE_INLINE;
2245         $inline_doc_state = STATE_INLINE_NAME !! 2220         $inline_doc_state = STATE_INLINE_NAME;
2246     } elsif ($decl_type eq 'function') {         2221     } elsif ($decl_type eq 'function') {
2247         process_proto_function($_, $file);    !! 2222         process_proto_function($_, $file);
2248     } else {                                     2223     } else {
2249         process_proto_type($_, $file);        !! 2224         process_proto_type($_, $file);
2250     }                                            2225     }
2251 }                                                2226 }
2252                                                  2227 
2253 #                                                2228 #
2254 # STATE_DOCBLOCK: within a DOC: block.           2229 # STATE_DOCBLOCK: within a DOC: block.
2255 #                                                2230 #
2256 sub process_docblock($$) {                       2231 sub process_docblock($$) {
2257     my $file = shift;                            2232     my $file = shift;
2258                                                  2233 
2259     if (/$doc_end/) {                            2234     if (/$doc_end/) {
2260         dump_doc_section($file, $section, $co !! 2235         dump_doc_section($file, $section, $contents);
2261         $section = $section_default;          !! 2236         $section = $section_default;
2262         $contents = "";                       !! 2237         $contents = "";
2263         $function = "";                       !! 2238         $function = "";
2264         %parameterdescs = ();                 !! 2239         %parameterdescs = ();
2265         %parametertypes = ();                 !! 2240         %parametertypes = ();
2266         @parameterlist = ();                  !! 2241         @parameterlist = ();
2267         %sections = ();                       !! 2242         %sections = ();
2268         @sectionlist = ();                    !! 2243         @sectionlist = ();
2269         $prototype = "";                      !! 2244         $prototype = "";
2270         $state = STATE_NORMAL;                !! 2245         $state = STATE_NORMAL;
2271     } elsif (/$doc_content/) {                   2246     } elsif (/$doc_content/) {
2272         if ( $1 eq "" )        {              !! 2247         if ( $1 eq "" ) {
2273             $contents .= $blankline;          !! 2248             $contents .= $blankline;
2274         } else {                              !! 2249         } else {
2275             $contents .= $1 . "\n";           !! 2250             $contents .= $1 . "\n";
2276         }                                     !! 2251         }
2277     }                                            2252     }
2278 }                                                2253 }
2279                                                  2254 
2280 #                                                2255 #
2281 # STATE_INLINE: docbook comments within a pro    2256 # STATE_INLINE: docbook comments within a prototype.
2282 #                                                2257 #
2283 sub process_inline($$) {                         2258 sub process_inline($$) {
2284     my $file = shift;                            2259     my $file = shift;
2285                                                  2260 
2286     # First line (state 1) needs to be a @par    2261     # First line (state 1) needs to be a @parameter
2287     if ($inline_doc_state == STATE_INLINE_NAM    2262     if ($inline_doc_state == STATE_INLINE_NAME && /$doc_inline_sect/o) {
2288         $section = $1;                        !! 2263         $section = $1;
2289         $contents = $2;                       !! 2264         $contents = $2;
2290         $new_start_line = $.;                 !! 2265         $new_start_line = $.;
2291         if ($contents ne "") {                !! 2266         if ($contents ne "") {
2292             while (substr($contents, 0, 1) eq !! 2267             while (substr($contents, 0, 1) eq " ") {
2293                 $contents = substr($contents, !! 2268                 $contents = substr($contents, 1);
2294             }                                 !! 2269             }
2295             $contents .= "\n";                !! 2270             $contents .= "\n";
2296         }                                     !! 2271         }
2297         $inline_doc_state = STATE_INLINE_TEXT !! 2272         $inline_doc_state = STATE_INLINE_TEXT;
2298         # Documentation block end */          !! 2273         # Documentation block end */
2299     } elsif (/$doc_inline_end/) {                2274     } elsif (/$doc_inline_end/) {
2300         if (($contents ne "") && ($contents n !! 2275         if (($contents ne "") && ($contents ne "\n")) {
2301             dump_section($file, $section, $co !! 2276             dump_section($file, $section, $contents);
2302             $section = $section_default;      !! 2277             $section = $section_default;
2303             $contents = "";                   !! 2278             $contents = "";
2304         }                                     !! 2279         }
2305         $state = STATE_PROTO;                 !! 2280         $state = STATE_PROTO;
2306         $inline_doc_state = STATE_INLINE_NA;  !! 2281         $inline_doc_state = STATE_INLINE_NA;
2307         # Regular text                        !! 2282         # Regular text
2308     } elsif (/$doc_content/) {                   2283     } elsif (/$doc_content/) {
2309         if ($inline_doc_state == STATE_INLINE !! 2284         if ($inline_doc_state == STATE_INLINE_TEXT) {
2310             $contents .= $1 . "\n";           !! 2285             $contents .= $1 . "\n";
2311             # nuke leading blank lines        !! 2286             # nuke leading blank lines
2312             if ($contents =~ /^\s*$/) {       !! 2287             if ($contents =~ /^\s*$/) {
2313                 $contents = "";               !! 2288                 $contents = "";
2314             }                                 !! 2289             }
2315         } elsif ($inline_doc_state == STATE_I !! 2290         } elsif ($inline_doc_state == STATE_INLINE_NAME) {
2316             $inline_doc_state = STATE_INLINE_ !! 2291             $inline_doc_state = STATE_INLINE_ERROR;
2317             emit_warning("${file}:$.", "Incor !! 2292             emit_warning("${file}:$.", "Incorrect use of kernel-doc format: $_");
2318         }                                     !! 2293         }
2319     }                                            2294     }
2320 }                                                2295 }
2321                                                  2296 
2322                                                  2297 
2323 sub process_file($) {                            2298 sub process_file($) {
2324     my $file;                                    2299     my $file;
2325     my $initial_section_counter = $section_co    2300     my $initial_section_counter = $section_counter;
2326     my ($orig_file) = @_;                        2301     my ($orig_file) = @_;
2327                                                  2302 
2328     $file = map_filename($orig_file);            2303     $file = map_filename($orig_file);
2329                                                  2304 
2330     if (!open(IN_FILE,"<$file")) {               2305     if (!open(IN_FILE,"<$file")) {
2331         print STDERR "Error: Cannot open file !! 2306         print STDERR "Error: Cannot open file $file\n";
2332         ++$errors;                            !! 2307         ++$errors;
2333         return;                               !! 2308         return;
2334     }                                            2309     }
2335                                                  2310 
2336     $. = 1;                                      2311     $. = 1;
2337                                                  2312 
2338     $section_counter = 0;                        2313     $section_counter = 0;
2339     while (<IN_FILE>) {                          2314     while (<IN_FILE>) {
2340         while (!/^ \*/ && s/\\\s*$//) {       !! 2315         while (s/\\\s*$//) {
2341             $_ .= <IN_FILE>;                  !! 2316             $_ .= <IN_FILE>;
2342         }                                     !! 2317         }
2343         # Replace tabs by spaces              !! 2318         # Replace tabs by spaces
2344         while ($_ =~ s/\t+/' ' x (length($&)     2319         while ($_ =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {};
2345         # Hand this line to the appropriate s !! 2320         # Hand this line to the appropriate state handler
2346         if ($state == STATE_NORMAL) {         !! 2321         if ($state == STATE_NORMAL) {
2347             process_normal();                 !! 2322             process_normal();
2348         } elsif ($state == STATE_NAME) {      !! 2323         } elsif ($state == STATE_NAME) {
2349             process_name($file, $_);          !! 2324             process_name($file, $_);
2350         } elsif ($state == STATE_BODY || $sta !! 2325         } elsif ($state == STATE_BODY || $state == STATE_BODY_MAYBE ||
2351                  $state == STATE_BODY_WITH_BL !! 2326                  $state == STATE_BODY_WITH_BLANK_LINE) {
2352             process_body($file, $_);          !! 2327             process_body($file, $_);
2353         } elsif ($state == STATE_INLINE) { #  !! 2328         } elsif ($state == STATE_INLINE) { # scanning for inline parameters
2354             process_inline($file, $_);        !! 2329             process_inline($file, $_);
2355         } elsif ($state == STATE_PROTO) {     !! 2330         } elsif ($state == STATE_PROTO) {
2356             process_proto($file, $_);         !! 2331             process_proto($file, $_);
2357         } elsif ($state == STATE_DOCBLOCK) {  !! 2332         } elsif ($state == STATE_DOCBLOCK) {
2358             process_docblock($file, $_);      !! 2333             process_docblock($file, $_);
2359         }                                     !! 2334         }
2360     }                                            2335     }
2361                                                  2336 
2362     # Make sure we got something interesting.    2337     # Make sure we got something interesting.
2363     if ($initial_section_counter == $section_    2338     if ($initial_section_counter == $section_counter && $
2364         output_mode ne "none") {              !! 2339         output_mode ne "none") {
2365         if ($output_selection == OUTPUT_INCLU !! 2340         if ($output_selection == OUTPUT_INCLUDE) {
2366             emit_warning("${file}:1", "'$_' n !! 2341             emit_warning("${file}:1", "'$_' not found\n")
2367                 for keys %function_table;     !! 2342                 for keys %function_table;
2368         } else {                              !! 2343         }
2369             emit_warning("${file}:1", "no str !! 2344         else {
2370         }                                     !! 2345             emit_warning("${file}:1", "no structured comments found\n");
                                                   >> 2346         }
2371     }                                            2347     }
2372     close IN_FILE;                               2348     close IN_FILE;
2373 }                                                2349 }
2374                                                  2350 
2375                                                  2351 
2376 if ($output_mode eq "rst") {                     2352 if ($output_mode eq "rst") {
2377     get_sphinx_version() if (!$sphinx_major); !! 2353         get_sphinx_version() if (!$sphinx_major);
2378 }                                                2354 }
2379                                                  2355 
2380 $kernelversion = get_kernel_version();           2356 $kernelversion = get_kernel_version();
2381                                                  2357 
2382 # generate a sequence of code that will splic    2358 # generate a sequence of code that will splice in highlighting information
2383 # using the s// operator.                        2359 # using the s// operator.
2384 for (my $k = 0; $k < @highlights; $k++) {        2360 for (my $k = 0; $k < @highlights; $k++) {
2385     my $pattern = $highlights[$k][0];            2361     my $pattern = $highlights[$k][0];
2386     my $result = $highlights[$k][1];             2362     my $result = $highlights[$k][1];
2387 #   print STDERR "scanning pattern:$pattern,     2363 #   print STDERR "scanning pattern:$pattern, highlight:($result)\n";
2388     $dohighlight .=  "\$contents =~ s:$patter    2364     $dohighlight .=  "\$contents =~ s:$pattern:$result:gs;\n";
2389 }                                                2365 }
2390                                                  2366 
2391 # Read the file that maps relative names to a    2367 # Read the file that maps relative names to absolute names for
2392 # separate source and object directories and     2368 # separate source and object directories and for shadow trees.
2393 if (open(SOURCE_MAP, "<.tmp_filelist.txt")) {    2369 if (open(SOURCE_MAP, "<.tmp_filelist.txt")) {
2394     my ($relname, $absname);                  !! 2370         my ($relname, $absname);
2395     while(<SOURCE_MAP>) {                     !! 2371         while(<SOURCE_MAP>) {
2396         chop();                               !! 2372                 chop();
2397         ($relname, $absname) = (split())[0..1 !! 2373                 ($relname, $absname) = (split())[0..1];
2398         $relname =~ s:^/+::;                  !! 2374                 $relname =~ s:^/+::;
2399         $source_map{$relname} = $absname;     !! 2375                 $source_map{$relname} = $absname;
2400     }                                         !! 2376         }
2401     close(SOURCE_MAP);                        !! 2377         close(SOURCE_MAP);
2402 }                                                2378 }
2403                                                  2379 
2404 if ($output_selection == OUTPUT_EXPORTED ||      2380 if ($output_selection == OUTPUT_EXPORTED ||
2405     $output_selection == OUTPUT_INTERNAL) {      2381     $output_selection == OUTPUT_INTERNAL) {
2406                                                  2382 
2407     push(@export_file_list, @ARGV);              2383     push(@export_file_list, @ARGV);
2408                                                  2384 
2409     foreach (@export_file_list) {                2385     foreach (@export_file_list) {
2410         chomp;                                !! 2386         chomp;
2411         process_export_file($_);              !! 2387         process_export_file($_);
2412     }                                            2388     }
2413 }                                                2389 }
2414                                                  2390 
2415 foreach (@ARGV) {                                2391 foreach (@ARGV) {
2416     chomp;                                       2392     chomp;
2417     process_file($_);                            2393     process_file($_);
2418 }                                                2394 }
2419 if ($verbose && $errors) {                       2395 if ($verbose && $errors) {
2420     print STDERR "$errors errors\n";          !! 2396   print STDERR "$errors errors\n";
2421 }                                                2397 }
2422 if ($verbose && $warnings) {                     2398 if ($verbose && $warnings) {
2423     print STDERR "$warnings warnings\n";      !! 2399   print STDERR "$warnings warnings\n";
2424 }                                                2400 }
2425                                                  2401 
2426 if ($Werror && $warnings) {                      2402 if ($Werror && $warnings) {
2427     print STDERR "$warnings warnings as Error    2403     print STDERR "$warnings warnings as Errors\n";
2428     exit($warnings);                             2404     exit($warnings);
2429 } else {                                         2405 } else {
2430     exit($output_mode eq "none" ? 0 : $errors    2406     exit($output_mode eq "none" ? 0 : $errors)
2431 }                                                2407 }
2432                                                  2408 
2433 __END__                                          2409 __END__
2434                                                  2410 
2435 =head1 OPTIONS                                   2411 =head1 OPTIONS
2436                                                  2412 
2437 =head2 Output format selection (mutually excl    2413 =head2 Output format selection (mutually exclusive):
2438                                                  2414 
2439 =over 8                                          2415 =over 8
2440                                                  2416 
2441 =item -man                                       2417 =item -man
2442                                                  2418 
2443 Output troff manual page format.                 2419 Output troff manual page format.
2444                                                  2420 
2445 =item -rst                                       2421 =item -rst
2446                                                  2422 
2447 Output reStructuredText format. This is the d    2423 Output reStructuredText format. This is the default.
2448                                                  2424 
2449 =item -none                                      2425 =item -none
2450                                                  2426 
2451 Do not output documentation, only warnings.      2427 Do not output documentation, only warnings.
2452                                                  2428 
2453 =back                                            2429 =back
2454                                                  2430 
2455 =head2 Output format modifiers                   2431 =head2 Output format modifiers
2456                                                  2432 
2457 =head3 reStructuredText only                     2433 =head3 reStructuredText only
2458                                                  2434 
2459 =over 8                                          2435 =over 8
2460                                                  2436 
2461 =item -sphinx-version VERSION                    2437 =item -sphinx-version VERSION
2462                                                  2438 
2463 Use the ReST C domain dialect compatible with    2439 Use the ReST C domain dialect compatible with a specific Sphinx Version.
2464                                                  2440 
2465 If not specified, kernel-doc will auto-detect    2441 If not specified, kernel-doc will auto-detect using the sphinx-build version
2466 found on PATH.                                   2442 found on PATH.
2467                                                  2443 
2468 =back                                            2444 =back
2469                                                  2445 
2470 =head2 Output selection (mutually exclusive):    2446 =head2 Output selection (mutually exclusive):
2471                                                  2447 
2472 =over 8                                          2448 =over 8
2473                                                  2449 
2474 =item -export                                    2450 =item -export
2475                                                  2451 
2476 Only output documentation for the symbols tha    2452 Only output documentation for the symbols that have been exported using
2477 EXPORT_SYMBOL() and related macros in any inp    2453 EXPORT_SYMBOL() and related macros in any input FILE or -export-file FILE.
2478                                                  2454 
2479 =item -internal                                  2455 =item -internal
2480                                                  2456 
2481 Only output documentation for the symbols tha    2457 Only output documentation for the symbols that have NOT been exported using
2482 EXPORT_SYMBOL() and related macros in any inp    2458 EXPORT_SYMBOL() and related macros in any input FILE or -export-file FILE.
2483                                                  2459 
2484 =item -function NAME                             2460 =item -function NAME
2485                                                  2461 
2486 Only output documentation for the given funct    2462 Only output documentation for the given function or DOC: section title.
2487 All other functions and DOC: sections are ign    2463 All other functions and DOC: sections are ignored.
2488                                                  2464 
2489 May be specified multiple times.                 2465 May be specified multiple times.
2490                                                  2466 
2491 =item -nosymbol NAME                             2467 =item -nosymbol NAME
2492                                                  2468 
2493 Exclude the specified symbol from the output     2469 Exclude the specified symbol from the output documentation.
2494                                                  2470 
2495 May be specified multiple times.                 2471 May be specified multiple times.
2496                                                  2472 
2497 =back                                            2473 =back
2498                                                  2474 
2499 =head2 Output selection modifiers:               2475 =head2 Output selection modifiers:
2500                                                  2476 
2501 =over 8                                          2477 =over 8
2502                                                  2478 
2503 =item -no-doc-sections                           2479 =item -no-doc-sections
2504                                                  2480 
2505 Do not output DOC: sections.                     2481 Do not output DOC: sections.
2506                                                  2482 
2507 =item -export-file FILE                          2483 =item -export-file FILE
2508                                                  2484 
2509 Specify an additional FILE in which to look f    2485 Specify an additional FILE in which to look for EXPORT_SYMBOL information.
2510                                                  2486 
2511 To be used with -export or -internal.            2487 To be used with -export or -internal.
2512                                                  2488 
2513 May be specified multiple times.                 2489 May be specified multiple times.
2514                                                  2490 
2515 =back                                            2491 =back
2516                                                  2492 
2517 =head3 reStructuredText only                     2493 =head3 reStructuredText only
2518                                                  2494 
2519 =over 8                                          2495 =over 8
2520                                                  2496 
2521 =item -enable-lineno                             2497 =item -enable-lineno
2522                                                  2498 
2523 Enable output of .. LINENO lines.                2499 Enable output of .. LINENO lines.
2524                                                  2500 
2525 =back                                            2501 =back
2526                                                  2502 
2527 =head2 Other parameters:                         2503 =head2 Other parameters:
2528                                                  2504 
2529 =over 8                                          2505 =over 8
2530                                                  2506 
2531 =item -h, -help                                  2507 =item -h, -help
2532                                                  2508 
2533 Print this help.                                 2509 Print this help.
2534                                                  2510 
2535 =item -v                                         2511 =item -v
2536                                                  2512 
2537 Verbose output, more warnings and other infor    2513 Verbose output, more warnings and other information.
2538                                                  2514 
2539 =item -Werror                                    2515 =item -Werror
2540                                                  2516 
2541 Treat warnings as errors.                        2517 Treat warnings as errors.
2542                                                  2518 
2543 =back                                            2519 =back
2544                                                  2520 
2545 =cut                                             2521 =cut
                                                      

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php