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