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