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