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