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