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