1 #!/usr/bin/env perl !! 1 #!/usr/bin/perl -w 2 # SPDX-License-Identifier: GPL-2.0 << 3 # vim: softtabstop=4 << 4 2 5 use warnings; << 6 use strict; 3 use strict; 7 4 8 ## Copyright (c) 1998 Michael Zucchi, All Righ 5 ## Copyright (c) 1998 Michael Zucchi, All Rights Reserved ## 9 ## Copyright (C) 2000, 1 Tim Waugh <twaugh@red 6 ## Copyright (C) 2000, 1 Tim Waugh <twaugh@redhat.com> ## 10 ## Copyright (C) 2001 Simon Huggins 7 ## Copyright (C) 2001 Simon Huggins ## 11 ## Copyright (C) 2005-2012 Randy Dunlap 8 ## Copyright (C) 2005-2012 Randy Dunlap ## 12 ## Copyright (C) 2012 Dan Luedtke 9 ## Copyright (C) 2012 Dan Luedtke ## 13 ## 10 ## ## 14 ## #define enhancements by Armin Kuster <akuste 11 ## #define enhancements by Armin Kuster <akuster@mvista.com> ## 15 ## Copyright (c) 2000 MontaVista Software, Inc 12 ## Copyright (c) 2000 MontaVista Software, Inc. ## 16 # !! 13 ## ## 17 # Copyright (C) 2022 Tomasz Warniełło (POD) !! 14 ## This software falls under the GNU General Public License. ## 18 !! 15 ## Please read the COPYING file for more information ## 19 use Pod::Usage qw/pod2usage/; << 20 << 21 =head1 NAME << 22 << 23 kernel-doc - Print formatted kernel documentat << 24 << 25 =head1 SYNOPSIS << 26 << 27 kernel-doc [-h] [-v] [-Werror] [-Wall] [-Wret << 28 [ -man | << 29 -rst [-sphinx-version VERSION] [-enable-l << 30 -none << 31 ] << 32 [ << 33 -export | << 34 -internal | << 35 [-function NAME] ... | << 36 [-nosymbol NAME] ... << 37 ] << 38 [-no-doc-sections] << 39 [-export-file FILE] ... << 40 FILE ... << 41 << 42 Run `kernel-doc -h` for details. << 43 16 44 =head1 DESCRIPTION !! 17 # 18/01/2001 - Cleanups >> 18 # Functions prototyped as foo(void) same as foo() >> 19 # Stop eval'ing where we don't need to. >> 20 # -- huggie@earth.li >> 21 >> 22 # 27/06/2001 - Allowed whitespace after initial "/**" and >> 23 # allowed comments before function declarations. >> 24 # -- Christian Kreibich <ck@whoop.org> >> 25 >> 26 # Still to do: >> 27 # - add perldoc documentation >> 28 # - Look more closely at some of the scarier bits :) >> 29 >> 30 # 26/05/2001 - Support for separate source and object trees. >> 31 # Return error code. >> 32 # Keith Owens <kaos@ocs.com.au> >> 33 >> 34 # 23/09/2001 - Added support for typedefs, structs, enums and unions >> 35 # Support for Context section; can be terminated using empty line >> 36 # Small fixes (like spaces vs. \s in regex) >> 37 # -- Tim Jansen <tim@tjansen.de> >> 38 >> 39 # 25/07/2012 - Added support for HTML5 >> 40 # -- Dan Luedtke <mail@danrl.de> >> 41 >> 42 sub usage { >> 43 my $message = <<"EOF"; >> 44 Usage: $0 [OPTION ...] FILE ... 45 45 46 Read C language source or header FILEs, extrac 46 Read C language source or header FILEs, extract embedded documentation comments, 47 and print formatted documentation to standard 47 and print formatted documentation to standard output. 48 48 49 The documentation comments are identified by t !! 49 The documentation comments are identified by "/**" opening comment mark. See 50 !! 50 Documentation/kernel-doc-nano-HOWTO.txt for the documentation comment syntax. 51 See Documentation/doc-guide/kernel-doc.rst for << 52 << 53 =cut << 54 51 55 # more perldoc at the end of the file !! 52 Output format selection (mutually exclusive): >> 53 -docbook Output DocBook format. >> 54 -html Output HTML format. >> 55 -html5 Output HTML5 format. >> 56 -list Output symbol list format. This is for use by docproc. >> 57 -man Output troff manual page format. This is the default. >> 58 -rst Output reStructuredText format. >> 59 -text Output plain text format. >> 60 >> 61 Output selection (mutually exclusive): >> 62 -export Only output documentation for symbols that have been >> 63 exported using EXPORT_SYMBOL() or EXPORT_SYMBOL_GPL() >> 64 in any input FILE or -export-file FILE. >> 65 -internal Only output documentation for symbols that have NOT been >> 66 exported using EXPORT_SYMBOL() or EXPORT_SYMBOL_GPL() >> 67 in any input FILE or -export-file FILE. >> 68 -function NAME Only output documentation for the given function(s) >> 69 or DOC: section title(s). All other functions and DOC: >> 70 sections are ignored. May be specified multiple times. >> 71 -nofunction NAME Do NOT output documentation for the given function(s); >> 72 only output documentation for the other functions and >> 73 DOC: sections. May be specified multiple times. >> 74 >> 75 Output selection modifiers: >> 76 -no-doc-sections Do not output DOC: sections. >> 77 -enable-lineno Enable output of #define LINENO lines. Only works with >> 78 reStructuredText format. >> 79 -export-file FILE Specify an additional FILE in which to look for >> 80 EXPORT_SYMBOL() and EXPORT_SYMBOL_GPL(). To be used with >> 81 -export or -internal. May be specified multiple times. >> 82 >> 83 Other parameters: >> 84 -v Verbose output, more warnings and other information. >> 85 -h Print this help. >> 86 >> 87 EOF >> 88 print $message; >> 89 exit 1; >> 90 } >> 91 >> 92 # >> 93 # format of comments. >> 94 # In the following table, (...)? signifies optional structure. >> 95 # (...)* signifies 0 or more structure elements >> 96 # /** >> 97 # * function_name(:)? (- short description)? >> 98 # (* @parameterx: (description of parameter x)?)* >> 99 # (* a blank line)? >> 100 # * (Description:)? (Description of function)? >> 101 # * (section header: (section description)? )* >> 102 # (*)?*/ >> 103 # >> 104 # So .. the trivial example would be: >> 105 # >> 106 # /** >> 107 # * my_function >> 108 # */ >> 109 # >> 110 # If the Description: header tag is omitted, then there must be a blank line >> 111 # after the last parameter specification. >> 112 # e.g. >> 113 # /** >> 114 # * my_function - does my stuff >> 115 # * @my_arg: its mine damnit >> 116 # * >> 117 # * Does my stuff explained. >> 118 # */ >> 119 # >> 120 # or, could also use: >> 121 # /** >> 122 # * my_function - does my stuff >> 123 # * @my_arg: its mine damnit >> 124 # * Description: Does my stuff explained. >> 125 # */ >> 126 # etc. >> 127 # >> 128 # Besides functions you can also write documentation for structs, unions, >> 129 # enums and typedefs. Instead of the function name you must write the name >> 130 # of the declaration; the struct/union/enum/typedef must always precede >> 131 # the name. Nesting of declarations is not supported. >> 132 # Use the argument mechanism to document members or constants. >> 133 # e.g. >> 134 # /** >> 135 # * struct my_struct - short description >> 136 # * @a: first member >> 137 # * @b: second member >> 138 # * >> 139 # * Longer description >> 140 # */ >> 141 # struct my_struct { >> 142 # int a; >> 143 # int b; >> 144 # /* private: */ >> 145 # int c; >> 146 # }; >> 147 # >> 148 # All descriptions can be multiline, except the short function description. >> 149 # >> 150 # For really longs structs, you can also describe arguments inside the >> 151 # body of the struct. >> 152 # eg. >> 153 # /** >> 154 # * struct my_struct - short description >> 155 # * @a: first member >> 156 # * @b: second member >> 157 # * >> 158 # * Longer description >> 159 # */ >> 160 # struct my_struct { >> 161 # int a; >> 162 # int b; >> 163 # /** >> 164 # * @c: This is longer description of C >> 165 # * >> 166 # * You can use paragraphs to describe arguments >> 167 # * using this method. >> 168 # */ >> 169 # int c; >> 170 # }; >> 171 # >> 172 # This should be use only for struct/enum members. >> 173 # >> 174 # You can also add additional sections. When documenting kernel functions you >> 175 # should document the "Context:" of the function, e.g. whether the functions >> 176 # can be called form interrupts. Unlike other sections you can end it with an >> 177 # empty line. >> 178 # A non-void function should have a "Return:" section describing the return >> 179 # value(s). >> 180 # Example-sections should contain the string EXAMPLE so that they are marked >> 181 # appropriately in DocBook. >> 182 # >> 183 # Example: >> 184 # /** >> 185 # * user_function - function that can only be called in user context >> 186 # * @a: some argument >> 187 # * Context: !in_interrupt() >> 188 # * >> 189 # * Some description >> 190 # * Example: >> 191 # * user_function(22); >> 192 # */ >> 193 # ... >> 194 # >> 195 # >> 196 # All descriptive text is further processed, scanning for the following special >> 197 # patterns, which are highlighted appropriately. >> 198 # >> 199 # 'funcname()' - function >> 200 # '$ENVVAR' - environmental variable >> 201 # '&struct_name' - name of a structure (up to two words including 'struct') >> 202 # '@parameter' - name of a parameter >> 203 # '%CONST' - name of a constant. 56 204 57 ## init lots of data 205 ## init lots of data 58 206 >> 207 59 my $errors = 0; 208 my $errors = 0; 60 my $warnings = 0; 209 my $warnings = 0; 61 my $anon_struct_union = 0; 210 my $anon_struct_union = 0; 62 211 63 # match expressions used to find embedded type 212 # match expressions used to find embedded type information 64 my $type_constant = '\b``([^\`]+)``\b'; !! 213 my $type_constant = '\%([-_\w]+)'; 65 my $type_constant2 = '\%([-_*\w]+)'; << 66 my $type_func = '(\w+)\(\)'; 214 my $type_func = '(\w+)\(\)'; 67 my $type_param = '\@(\w*((\.\w+)|(->\w+))*(\.\ !! 215 my $type_param = '\@(\w+(\.\.\.)?)'; 68 my $type_param_ref = '([\!~\*]?)\@(\w*((\.\w+) << 69 my $type_fp_param = '\@(\w+)\(\)'; # Special 216 my $type_fp_param = '\@(\w+)\(\)'; # Special RST handling for func ptr params 70 my $type_fp_param2 = '\@(\w+->\S+)\(\)'; # Sp !! 217 my $type_struct = '\&((struct\s*)*[_\w]+)'; >> 218 my $type_struct_xml = '\\&((struct\s*)*[_\w]+)'; 71 my $type_env = '(\$\w+)'; 219 my $type_env = '(\$\w+)'; 72 my $type_enum = '\&(enum\s*([_\w]+))'; !! 220 my $type_enum_full = '\&(enum)\s*([_\w]+)'; 73 my $type_struct = '\&(struct\s*([_\w]+))'; !! 221 my $type_struct_full = '\&(struct)\s*([_\w]+)'; 74 my $type_typedef = '\&(typedef\s*([_\w]+))'; !! 222 my $type_typedef_full = '\&(typedef)\s*([_\w]+)'; 75 my $type_union = '\&(union\s*([_\w]+))'; !! 223 my $type_union_full = '\&(union)\s*([_\w]+)'; 76 my $type_member = '\&([_\w]+)(\.|->)([_\w]+)'; !! 224 my $type_member = '\&([_\w]+)((\.|->)[_\w]+)'; 77 my $type_fallback = '\&([_\w]+)'; << 78 my $type_member_func = $type_member . '\(\)'; 225 my $type_member_func = $type_member . '\(\)'; 79 226 80 # Output conversion substitutions. 227 # Output conversion substitutions. 81 # One for each output format 228 # One for each output format 82 229 >> 230 # these work fairly well >> 231 my @highlights_html = ( >> 232 [$type_constant, "<i>\$1</i>"], >> 233 [$type_func, "<b>\$1</b>"], >> 234 [$type_struct_xml, "<i>\$1</i>"], >> 235 [$type_env, "<b><i>\$1</i></b>"], >> 236 [$type_param, "<tt><b>\$1</b></tt>"] >> 237 ); >> 238 my $local_lt = "\\\\\\\\lt:"; >> 239 my $local_gt = "\\\\\\\\gt:"; >> 240 my $blankline_html = $local_lt . "p" . $local_gt; # was "<p>" >> 241 >> 242 # html version 5 >> 243 my @highlights_html5 = ( >> 244 [$type_constant, "<span class=\"const\">\$1</span>"], >> 245 [$type_func, "<span class=\"func\">\$1</span>"], >> 246 [$type_struct_xml, "<span class=\"struct\">\$1</span>"], >> 247 [$type_env, "<span class=\"env\">\$1</span>"], >> 248 [$type_param, "<span class=\"param\">\$1</span>]"] >> 249 ); >> 250 my $blankline_html5 = $local_lt . "br /" . $local_gt; >> 251 >> 252 # XML, docbook format >> 253 my @highlights_xml = ( >> 254 ["([^=])\\\"([^\\\"<]+)\\\"", "\$1<quote>\$2</quote>"], >> 255 [$type_constant, "<constant>\$1</constant>"], >> 256 [$type_struct_xml, "<structname>\$1</structname>"], >> 257 [$type_param, "<parameter>\$1</parameter>"], >> 258 [$type_func, "<function>\$1</function>"], >> 259 [$type_env, "<envar>\$1</envar>"] >> 260 ); >> 261 my $blankline_xml = $local_lt . "/para" . $local_gt . $local_lt . "para" . $local_gt . "\n"; >> 262 >> 263 # gnome, docbook format >> 264 my @highlights_gnome = ( >> 265 [$type_constant, "<replaceable class=\"option\">\$1</replaceable>"], >> 266 [$type_func, "<function>\$1</function>"], >> 267 [$type_struct, "<structname>\$1</structname>"], >> 268 [$type_env, "<envar>\$1</envar>"], >> 269 [$type_param, "<parameter>\$1</parameter>" ] >> 270 ); >> 271 my $blankline_gnome = "</para><para>\n"; >> 272 83 # these are pretty rough 273 # these are pretty rough 84 my @highlights_man = ( 274 my @highlights_man = ( 85 [$type_constant, "\$1"], !! 275 [$type_constant, "\$1"], 86 [$type_constant2, "\$1"], !! 276 [$type_func, "\\\\fB\$1\\\\fP"], 87 [$type_func, "\\\\fB\$1\\\\fP"], !! 277 [$type_struct, "\\\\fI\$1\\\\fP"], 88 [$type_enum, "\\\\fI\$1\\\\fP"], !! 278 [$type_param, "\\\\fI\$1\\\\fP"] 89 [$type_struct, "\\\\fI\$1\\\\fP"], !! 279 ); 90 [$type_typedef, "\\\\fI\$1\\\\fP"], << 91 [$type_union, "\\\\fI\$1\\\\fP"], << 92 [$type_param, "\\\\fI\$1\\\\fP"], << 93 [$type_param_ref, "\\\\fI\$1\$2\\\\fP"], << 94 [$type_member, "\\\\fI\$1\$2\$3\\\\fP"], << 95 [$type_fallback, "\\\\fI\$1\\\\fP"] << 96 ); << 97 my $blankline_man = ""; 280 my $blankline_man = ""; 98 281 >> 282 # text-mode >> 283 my @highlights_text = ( >> 284 [$type_constant, "\$1"], >> 285 [$type_func, "\$1"], >> 286 [$type_struct, "\$1"], >> 287 [$type_param, "\$1"] >> 288 ); >> 289 my $blankline_text = ""; >> 290 99 # rst-mode 291 # rst-mode 100 my @highlights_rst = ( 292 my @highlights_rst = ( 101 [$type_constant, "``\$1``"], !! 293 [$type_constant, "``\$1``"], 102 [$type_constant2, "``\$1``"], !! 294 # Note: need to escape () to avoid func matching later 103 !! 295 [$type_member_func, "\\:c\\:type\\:`\$1\$2\\\\(\\\\) <\$1>`"], 104 # Note: need to escape () to avoid func ma !! 296 [$type_member, "\\:c\\:type\\:`\$1\$2 <\$1>`"], 105 [$type_member_func, "\\:c\\:type\\:`\$1\$2 !! 297 [$type_fp_param, "**\$1\\\\(\\\\)**"], 106 [$type_member, "\\:c\\:type\\:`\$1\$2\$3 < !! 298 [$type_func, "\\:c\\:func\\:`\$1()`"], 107 [$type_fp_param, "**\$1\\\\(\\\\)**"], !! 299 [$type_struct_full, "\\:c\\:type\\:`\$1 \$2 <\$2>`"], 108 [$type_fp_param2, "**\$1\\\\(\\\\)**"], !! 300 [$type_enum_full, "\\:c\\:type\\:`\$1 \$2 <\$2>`"], 109 [$type_func, "\$1()"], !! 301 [$type_typedef_full, "\\:c\\:type\\:`\$1 \$2 <\$2>`"], 110 [$type_enum, "\\:c\\:type\\:`\$1 <\$2>`"], !! 302 [$type_union_full, "\\:c\\:type\\:`\$1 \$2 <\$2>`"], 111 [$type_struct, "\\:c\\:type\\:`\$1 <\$2>`" !! 303 # in rst this can refer to any type 112 [$type_typedef, "\\:c\\:type\\:`\$1 <\$2>` !! 304 [$type_struct, "\\:c\\:type\\:`\$1`"], 113 [$type_union, "\\:c\\:type\\:`\$1 <\$2>`"] !! 305 [$type_param, "**\$1**"] 114 !! 306 ); 115 # in rst this can refer to any type << 116 [$type_fallback, "\\:c\\:type\\:`\$1`"], << 117 [$type_param_ref, "**\$1\$2**"] << 118 ); << 119 my $blankline_rst = "\n"; 307 my $blankline_rst = "\n"; 120 308 >> 309 # list mode >> 310 my @highlights_list = ( >> 311 [$type_constant, "\$1"], >> 312 [$type_func, "\$1"], >> 313 [$type_struct, "\$1"], >> 314 [$type_param, "\$1"] >> 315 ); >> 316 my $blankline_list = ""; >> 317 121 # read arguments 318 # read arguments 122 if ($#ARGV == -1) { 319 if ($#ARGV == -1) { 123 pod2usage( !! 320 usage(); 124 -message => "No arguments!\n", << 125 -exitval => 1, << 126 -verbose => 99, << 127 -sections => 'SYNOPSIS', << 128 -output => \*STDERR, << 129 ); << 130 } 321 } 131 322 132 my $kernelversion; 323 my $kernelversion; 133 my ($sphinx_major, $sphinx_minor, $sphinx_patc << 134 << 135 my $dohighlight = ""; 324 my $dohighlight = ""; 136 325 137 my $verbose = 0; 326 my $verbose = 0; 138 my $Werror = 0; !! 327 my $output_mode = "man"; 139 my $Wreturn = 0; << 140 my $Wshort_desc = 0; << 141 my $Wcontents_before_sections = 0; << 142 my $output_mode = "rst"; << 143 my $output_preformatted = 0; 328 my $output_preformatted = 0; 144 my $no_doc_sections = 0; 329 my $no_doc_sections = 0; 145 my $enable_lineno = 0; 330 my $enable_lineno = 0; 146 my @highlights = @highlights_rst; !! 331 my @highlights = @highlights_man; 147 my $blankline = $blankline_rst; !! 332 my $blankline = $blankline_man; 148 my $modulename = "Kernel API"; 333 my $modulename = "Kernel API"; 149 334 150 use constant { 335 use constant { 151 OUTPUT_ALL => 0, # output all sym 336 OUTPUT_ALL => 0, # output all symbols and doc sections 152 OUTPUT_INCLUDE => 1, # output only sp 337 OUTPUT_INCLUDE => 1, # output only specified symbols 153 OUTPUT_EXPORTED => 2, # output exporte !! 338 OUTPUT_EXCLUDE => 2, # output everything except specified symbols 154 OUTPUT_INTERNAL => 3, # output non-exp !! 339 OUTPUT_EXPORTED => 3, # output exported symbols >> 340 OUTPUT_INTERNAL => 4, # output non-exported symbols 155 }; 341 }; 156 my $output_selection = OUTPUT_ALL; 342 my $output_selection = OUTPUT_ALL; 157 my $show_not_found = 0; # No longer used !! 343 my $show_not_found = 0; 158 344 159 my @export_file_list; 345 my @export_file_list; 160 346 161 my @build_time; 347 my @build_time; 162 if (defined($ENV{'KBUILD_BUILD_TIMESTAMP'}) && 348 if (defined($ENV{'KBUILD_BUILD_TIMESTAMP'}) && 163 (my $seconds = `date -d"${ENV{'KBUILD_BUIL 349 (my $seconds = `date -d"${ENV{'KBUILD_BUILD_TIMESTAMP'}}" +%s`) ne '') { 164 @build_time = gmtime($seconds); 350 @build_time = gmtime($seconds); 165 } else { 351 } else { 166 @build_time = localtime; 352 @build_time = localtime; 167 } 353 } 168 354 169 my $man_date = ('January', 'February', 'March' 355 my $man_date = ('January', 'February', 'March', 'April', 'May', 'June', 170 'July', 'August', 'September', !! 356 'July', 'August', 'September', 'October', 171 'November', 'December')[$build !! 357 'November', 'December')[$build_time[4]] . 172 " " . ($build_time[5]+1900); !! 358 " " . ($build_time[5]+1900); 173 359 174 # Essentially these are globals. 360 # Essentially these are globals. 175 # They probably want to be tidied up, made mor 361 # They probably want to be tidied up, made more localised or something. 176 # CAVEAT EMPTOR! Some of the others I localis 362 # CAVEAT EMPTOR! Some of the others I localised may not want to be, which 177 # could cause "use of undefined value" or othe 363 # could cause "use of undefined value" or other bugs. 178 my ($function, %function_table, %parametertype 364 my ($function, %function_table, %parametertypes, $declaration_purpose); 179 my %nosymbol_table = (); << 180 my $declaration_start_line; 365 my $declaration_start_line; 181 my ($type, $declaration_name, $return_type); 366 my ($type, $declaration_name, $return_type); 182 my ($newsection, $newcontents, $prototype, $br 367 my ($newsection, $newcontents, $prototype, $brcount, %source_map); 183 368 184 if (defined($ENV{'KBUILD_VERBOSE'}) && $ENV{'K !! 369 if (defined($ENV{'KBUILD_VERBOSE'})) { 185 $verbose = 1; !! 370 $verbose = "$ENV{'KBUILD_VERBOSE'}"; 186 } << 187 << 188 if (defined($ENV{'KCFLAGS'})) { << 189 my $kcflags = "$ENV{'KCFLAGS'}"; << 190 << 191 if ($kcflags =~ /(\s|^)-Werror(\s|$)/) { << 192 $Werror = 1; << 193 } << 194 } << 195 << 196 # reading this variable is for backwards compa << 197 # someone was calling it with the variable fro << 198 # kernel's build system << 199 if (defined($ENV{'KDOC_WERROR'})) { << 200 $Werror = "$ENV{'KDOC_WERROR'}"; << 201 } 371 } 202 # other environment variables are converted to << 203 # arguments in cmd_checkdoc in the build syste << 204 372 205 # Generated docbook code is inserted in a temp 373 # Generated docbook code is inserted in a template at a point where 206 # docbook v3.1 requires a non-zero sequence of 374 # docbook v3.1 requires a non-zero sequence of RefEntry's; see: 207 # https://www.oasis-open.org/docbook/documenta !! 375 # http://www.oasis-open.org/docbook/documentation/reference/html/refentry.html 208 # We keep track of number of generated entries 376 # We keep track of number of generated entries and generate a dummy 209 # if needs be to ensure the expanded template 377 # if needs be to ensure the expanded template can be postprocessed 210 # into html. 378 # into html. 211 my $section_counter = 0; 379 my $section_counter = 0; 212 380 213 my $lineprefix=""; 381 my $lineprefix=""; 214 382 215 # Parser states 383 # Parser states 216 use constant { 384 use constant { 217 STATE_NORMAL => 0, # normal !! 385 STATE_NORMAL => 0, # normal code 218 STATE_NAME => 1, # looking !! 386 STATE_NAME => 1, # looking for function name 219 STATE_BODY_MAYBE => 2, # body - !! 387 STATE_FIELD => 2, # scanning field start 220 STATE_BODY => 3, # the bod !! 388 STATE_PROTO => 3, # scanning prototype 221 STATE_BODY_WITH_BLANK_LINE => 4, # the bod !! 389 STATE_DOCBLOCK => 4, # documentation block 222 STATE_PROTO => 5, # scannin !! 390 STATE_INLINE => 5, # gathering documentation outside main block 223 STATE_DOCBLOCK => 6, # documen << 224 STATE_INLINE => 7, # gatheri << 225 }; 391 }; 226 my $state; 392 my $state; 227 my $in_doc_sect; 393 my $in_doc_sect; 228 my $leading_space; << 229 394 230 # Inline documentation state 395 # Inline documentation state 231 use constant { 396 use constant { 232 STATE_INLINE_NA => 0, # not applicable 397 STATE_INLINE_NA => 0, # not applicable ($state != STATE_INLINE) 233 STATE_INLINE_NAME => 1, # looking for me 398 STATE_INLINE_NAME => 1, # looking for member name (@foo:) 234 STATE_INLINE_TEXT => 2, # looking for me 399 STATE_INLINE_TEXT => 2, # looking for member documentation 235 STATE_INLINE_END => 3, # done 400 STATE_INLINE_END => 3, # done 236 STATE_INLINE_ERROR => 4, # error - Commen 401 STATE_INLINE_ERROR => 4, # error - Comment without header was found. 237 # Spit a warning 402 # Spit a warning as it's not 238 # proper kernel- 403 # proper kernel-doc and ignore the rest. 239 }; 404 }; 240 my $inline_doc_state; 405 my $inline_doc_state; 241 406 242 #declaration types: can be 407 #declaration types: can be 243 # 'function', 'struct', 'union', 'enum', 'type 408 # 'function', 'struct', 'union', 'enum', 'typedef' 244 my $decl_type; 409 my $decl_type; 245 410 246 # Name of the kernel-doc identifier for non-DO << 247 my $identifier; << 248 << 249 my $doc_start = '^/\*\*\s*$'; # Allow whitespa 411 my $doc_start = '^/\*\*\s*$'; # Allow whitespace at end of comment start. 250 my $doc_end = '\*/'; 412 my $doc_end = '\*/'; 251 my $doc_com = '\s*\*\s*'; 413 my $doc_com = '\s*\*\s*'; 252 my $doc_com_body = '\s*\* ?'; 414 my $doc_com_body = '\s*\* ?'; 253 my $doc_decl = $doc_com . '(\w+)'; 415 my $doc_decl = $doc_com . '(\w+)'; 254 # @params and a strictly limited set of suppor 416 # @params and a strictly limited set of supported section names 255 # Specifically: !! 417 my $doc_sect = $doc_com . 256 # Match @word: !! 418 '\s*(\@[.\w]+|\@\.\.\.|description|context|returns?|notes?|examples?)\s*:(.*)'; 257 # @...: << 258 # @{section-name}: << 259 # while trying to not match literal block star << 260 # << 261 my $doc_sect = $doc_com . << 262 '\s*(\@[.\w]+|\@\.\.\.|description|context << 263 my $doc_content = $doc_com_body . '(.*)'; 419 my $doc_content = $doc_com_body . '(.*)'; 264 my $doc_block = $doc_com . 'DOC:\s*(.*)?'; 420 my $doc_block = $doc_com . 'DOC:\s*(.*)?'; 265 my $doc_inline_start = '^\s*/\*\*\s*$'; 421 my $doc_inline_start = '^\s*/\*\*\s*$'; 266 my $doc_inline_sect = '\s*\*\s*(@\s*[\w][\w\.] !! 422 my $doc_inline_sect = '\s*\*\s*(@[\w\s]+):(.*)'; 267 my $doc_inline_end = '^\s*\*/\s*$'; 423 my $doc_inline_end = '^\s*\*/\s*$'; 268 my $doc_inline_oneline = '^\s*/\*\*\s*(@[\w\s] 424 my $doc_inline_oneline = '^\s*/\*\*\s*(@[\w\s]+):\s*(.*)\s*\*/\s*$'; 269 my $export_symbol = '^\s*EXPORT_SYMBOL(_GPL)?\ 425 my $export_symbol = '^\s*EXPORT_SYMBOL(_GPL)?\s*\(\s*(\w+)\s*\)\s*;'; 270 my $export_symbol_ns = '^\s*EXPORT_SYMBOL_NS(_ << 271 my $function_pointer = qr{([^\(]*\(\*)\s*\)\s* << 272 my $attribute = qr{__attribute__\s*\(\([a-z0-9 << 273 426 274 my %parameterdescs; 427 my %parameterdescs; 275 my %parameterdesc_start_lines; 428 my %parameterdesc_start_lines; 276 my @parameterlist; 429 my @parameterlist; 277 my %sections; 430 my %sections; 278 my @sectionlist; 431 my @sectionlist; 279 my %section_start_lines; 432 my %section_start_lines; 280 my $sectcheck; 433 my $sectcheck; 281 my $struct_actual; 434 my $struct_actual; 282 435 283 my $contents = ""; 436 my $contents = ""; 284 my $new_start_line = 0; 437 my $new_start_line = 0; 285 438 286 # the canonical section names. see also $doc_s 439 # the canonical section names. see also $doc_sect above. 287 my $section_default = "Description"; # defa 440 my $section_default = "Description"; # default section 288 my $section_intro = "Introduction"; 441 my $section_intro = "Introduction"; 289 my $section = $section_default; 442 my $section = $section_default; 290 my $section_context = "Context"; 443 my $section_context = "Context"; 291 my $section_return = "Return"; 444 my $section_return = "Return"; 292 445 293 my $undescribed = "-- undescribed --"; 446 my $undescribed = "-- undescribed --"; 294 447 295 reset_state(); 448 reset_state(); 296 449 297 while ($ARGV[0] =~ m/^--?(.*)/) { !! 450 while ($ARGV[0] =~ m/^-(.*)/) { 298 my $cmd = $1; !! 451 my $cmd = shift @ARGV; 299 shift @ARGV; !! 452 if ($cmd eq "-html") { 300 if ($cmd eq "man") { !! 453 $output_mode = "html"; 301 $output_mode = "man"; !! 454 @highlights = @highlights_html; 302 @highlights = @highlights_man; !! 455 $blankline = $blankline_html; 303 $blankline = $blankline_man; !! 456 } elsif ($cmd eq "-html5") { 304 } elsif ($cmd eq "rst") { !! 457 $output_mode = "html5"; 305 $output_mode = "rst"; !! 458 @highlights = @highlights_html5; 306 @highlights = @highlights_rst; !! 459 $blankline = $blankline_html5; 307 $blankline = $blankline_rst; !! 460 } elsif ($cmd eq "-man") { 308 } elsif ($cmd eq "none") { !! 461 $output_mode = "man"; 309 $output_mode = "none"; !! 462 @highlights = @highlights_man; 310 } elsif ($cmd eq "module") { # not needed !! 463 $blankline = $blankline_man; 311 $modulename = shift @ARGV; !! 464 } elsif ($cmd eq "-text") { 312 } elsif ($cmd eq "function") { # to only o !! 465 $output_mode = "text"; 313 $output_selection = OUTPUT_INCLUDE; !! 466 @highlights = @highlights_text; 314 $function = shift @ARGV; !! 467 $blankline = $blankline_text; 315 $function_table{$function} = 1; !! 468 } elsif ($cmd eq "-rst") { 316 } elsif ($cmd eq "nosymbol") { # Exclude s !! 469 $output_mode = "rst"; 317 my $symbol = shift @ARGV; !! 470 @highlights = @highlights_rst; 318 $nosymbol_table{$symbol} = 1; !! 471 $blankline = $blankline_rst; 319 } elsif ($cmd eq "export") { # only export !! 472 } elsif ($cmd eq "-docbook") { 320 $output_selection = OUTPUT_EXPORTED; !! 473 $output_mode = "xml"; 321 %function_table = (); !! 474 @highlights = @highlights_xml; 322 } elsif ($cmd eq "internal") { # only non- !! 475 $blankline = $blankline_xml; 323 $output_selection = OUTPUT_INTERNAL; !! 476 } elsif ($cmd eq "-list") { 324 %function_table = (); !! 477 $output_mode = "list"; 325 } elsif ($cmd eq "export-file") { !! 478 @highlights = @highlights_list; 326 my $file = shift @ARGV; !! 479 $blankline = $blankline_list; 327 push(@export_file_list, $file); !! 480 } elsif ($cmd eq "-gnome") { 328 } elsif ($cmd eq "v") { !! 481 $output_mode = "gnome"; 329 $verbose = 1; !! 482 @highlights = @highlights_gnome; 330 } elsif ($cmd eq "Werror") { !! 483 $blankline = $blankline_gnome; 331 $Werror = 1; !! 484 } elsif ($cmd eq "-module") { # not needed for XML, inherits from calling document 332 } elsif ($cmd eq "Wreturn") { !! 485 $modulename = shift @ARGV; 333 $Wreturn = 1; !! 486 } elsif ($cmd eq "-function") { # to only output specific functions 334 } elsif ($cmd eq "Wshort-desc" or $cmd eq !! 487 $output_selection = OUTPUT_INCLUDE; 335 $Wshort_desc = 1; !! 488 $function = shift @ARGV; 336 } elsif ($cmd eq "Wcontents-before-section !! 489 $function_table{$function} = 1; 337 $Wcontents_before_sections = 1; !! 490 } elsif ($cmd eq "-nofunction") { # output all except specific functions 338 } elsif ($cmd eq "Wall") { !! 491 $output_selection = OUTPUT_EXCLUDE; 339 $Wreturn = 1; !! 492 $function = shift @ARGV; 340 $Wshort_desc = 1; !! 493 $function_table{$function} = 1; 341 $Wcontents_before_sections = 1; !! 494 } elsif ($cmd eq "-export") { # only exported symbols 342 } elsif (($cmd eq "h") || ($cmd eq "help") !! 495 $output_selection = OUTPUT_EXPORTED; 343 pod2usage(-exitval => 0, -verbose => 2 !! 496 %function_table = (); 344 } elsif ($cmd eq 'no-doc-sections') { !! 497 } elsif ($cmd eq "-internal") { # only non-exported symbols 345 $no_doc_sections = 1; !! 498 $output_selection = OUTPUT_INTERNAL; 346 } elsif ($cmd eq 'enable-lineno') { !! 499 %function_table = (); 347 $enable_lineno = 1; !! 500 } elsif ($cmd eq "-export-file") { 348 } elsif ($cmd eq 'show-not-found') { !! 501 my $file = shift @ARGV; 349 $show_not_found = 1; # A no-op but do !! 502 push(@export_file_list, $file); 350 } elsif ($cmd eq "sphinx-version") { !! 503 } elsif ($cmd eq "-v") { 351 my $ver_string = shift @ARGV; !! 504 $verbose = 1; 352 if ($ver_string =~ m/^(\d+)(\.\d+)?(\. !! 505 } elsif (($cmd eq "-h") || ($cmd eq "--help")) { 353 $sphinx_major = $1; !! 506 usage(); 354 if (defined($2)) { !! 507 } elsif ($cmd eq '-no-doc-sections') { 355 $sphinx_minor = substr($2,1); !! 508 $no_doc_sections = 1; 356 } else { !! 509 } elsif ($cmd eq '-enable-lineno') { 357 $sphinx_minor = 0; !! 510 $enable_lineno = 1; 358 } !! 511 } elsif ($cmd eq '-show-not-found') { 359 if (defined($3)) { !! 512 $show_not_found = 1; 360 $sphinx_patch = substr($3,1) << 361 } else { << 362 $sphinx_patch = 0; << 363 } << 364 } else { << 365 die "Sphinx version should either << 366 } << 367 } else { << 368 # Unknown argument << 369 pod2usage( << 370 -message => "Argument unknown!\n", << 371 -exitval => 1, << 372 -verbose => 99, << 373 -sections => 'SYNOPSIS', << 374 -output => \*STDERR, << 375 ); << 376 } << 377 if ($#ARGV < 0){ << 378 pod2usage( << 379 -message => "FILE argument missing << 380 -exitval => 1, << 381 -verbose => 99, << 382 -sections => 'SYNOPSIS', << 383 -output => \*STDERR, << 384 ); << 385 } 513 } 386 } 514 } 387 515 388 # continue execution near EOF; 516 # continue execution near EOF; 389 517 390 # The C domain dialect changed on Sphinx 3. So << 391 # version in order to produce the right tags. << 392 sub findprog($) << 393 { << 394 foreach(split(/:/, $ENV{PATH})) { << 395 return "$_/$_[0]" if(-x "$_/$_[0]"); << 396 } << 397 } << 398 << 399 sub get_sphinx_version() << 400 { << 401 my $ver; << 402 << 403 my $cmd = "sphinx-build"; << 404 if (!findprog($cmd)) { << 405 my $cmd = "sphinx-build3"; << 406 if (!findprog($cmd)) { << 407 $sphinx_major = 1; << 408 $sphinx_minor = 2; << 409 $sphinx_patch = 0; << 410 printf STDERR "Warning: Sphinx ver << 411 $sphinx_major, $sphinx_mino << 412 return; << 413 } << 414 } << 415 << 416 open IN, "$cmd --version 2>&1 |"; << 417 while (<IN>) { << 418 if (m/^\s*sphinx-build\s+([\d]+)\.([\d << 419 $sphinx_major = $1; << 420 $sphinx_minor = $2; << 421 $sphinx_patch = $3; << 422 last; << 423 } << 424 # Sphinx 1.2.x uses a different format << 425 if (m/^\s*Sphinx.*\s+([\d]+)\.([\d\.]+ << 426 $sphinx_major = $1; << 427 $sphinx_minor = $2; << 428 $sphinx_patch = $3; << 429 last; << 430 } << 431 } << 432 close IN; << 433 } << 434 << 435 # get kernel version from env 518 # get kernel version from env 436 sub get_kernel_version() { 519 sub get_kernel_version() { 437 my $version = 'unknown kernel version'; 520 my $version = 'unknown kernel version'; 438 521 439 if (defined($ENV{'KERNELVERSION'})) { 522 if (defined($ENV{'KERNELVERSION'})) { 440 $version = $ENV{'KERNELVERSION'}; !! 523 $version = $ENV{'KERNELVERSION'}; 441 } 524 } 442 return $version; 525 return $version; 443 } 526 } 444 527 445 # 528 # 446 sub print_lineno { 529 sub print_lineno { 447 my $lineno = shift; 530 my $lineno = shift; 448 if ($enable_lineno && defined($lineno)) { 531 if ($enable_lineno && defined($lineno)) { 449 print ".. LINENO " . $lineno . "\n"; !! 532 print "#define LINENO " . $lineno . "\n"; 450 } 533 } 451 } 534 } 452 << 453 sub emit_warning { << 454 my $location = shift; << 455 my $msg = shift; << 456 print STDERR "$location: warning: $msg"; << 457 ++$warnings; << 458 } << 459 ## 535 ## 460 # dumps section contents to arrays/hashes inte 536 # dumps section contents to arrays/hashes intended for that purpose. 461 # 537 # 462 sub dump_section { 538 sub dump_section { 463 my $file = shift; 539 my $file = shift; 464 my $name = shift; 540 my $name = shift; 465 my $contents = join "\n", @_; 541 my $contents = join "\n", @_; 466 542 467 if ($name =~ m/$type_param/) { 543 if ($name =~ m/$type_param/) { 468 $name = $1; !! 544 $name = $1; 469 $parameterdescs{$name} = $contents; !! 545 $parameterdescs{$name} = $contents; 470 $sectcheck = $sectcheck . $name . " "; !! 546 $sectcheck = $sectcheck . $name . " "; 471 $parameterdesc_start_lines{$name} = $n 547 $parameterdesc_start_lines{$name} = $new_start_line; 472 $new_start_line = 0; 548 $new_start_line = 0; 473 } elsif ($name eq "@\.\.\.") { 549 } elsif ($name eq "@\.\.\.") { 474 $name = "..."; !! 550 $name = "..."; 475 $parameterdescs{$name} = $contents; !! 551 $parameterdescs{$name} = $contents; 476 $sectcheck = $sectcheck . $name . " "; !! 552 $sectcheck = $sectcheck . $name . " "; 477 $parameterdesc_start_lines{$name} = $n 553 $parameterdesc_start_lines{$name} = $new_start_line; 478 $new_start_line = 0; 554 $new_start_line = 0; 479 } else { 555 } else { 480 if (defined($sections{$name}) && ($sec !! 556 if (defined($sections{$name}) && ($sections{$name} ne "")) { 481 # Only warn on user specified dupl !! 557 # Only warn on user specified duplicate section names. 482 if ($name ne $section_default) { !! 558 if ($name ne $section_default) { 483 emit_warning("${file}:$.", "du !! 559 print STDERR "${file}:$.: warning: duplicate section name '$name'\n"; 484 } !! 560 ++$warnings; 485 $sections{$name} .= $contents; !! 561 } 486 } else { !! 562 $sections{$name} .= $contents; 487 $sections{$name} = $contents; !! 563 } else { 488 push @sectionlist, $name; !! 564 $sections{$name} = $contents; >> 565 push @sectionlist, $name; 489 $section_start_lines{$name} = $new 566 $section_start_lines{$name} = $new_start_line; 490 $new_start_line = 0; 567 $new_start_line = 0; 491 } !! 568 } 492 } 569 } 493 } 570 } 494 571 495 ## 572 ## 496 # dump DOC: section after checking that it sho 573 # dump DOC: section after checking that it should go out 497 # 574 # 498 sub dump_doc_section { 575 sub dump_doc_section { 499 my $file = shift; 576 my $file = shift; 500 my $name = shift; 577 my $name = shift; 501 my $contents = join "\n", @_; 578 my $contents = join "\n", @_; 502 579 503 if ($no_doc_sections) { 580 if ($no_doc_sections) { 504 return; 581 return; 505 } 582 } 506 583 507 return if (defined($nosymbol_table{$name}) << 508 << 509 if (($output_selection == OUTPUT_ALL) || 584 if (($output_selection == OUTPUT_ALL) || 510 (($output_selection == OUTPUT_INCLUDE) !! 585 ($output_selection == OUTPUT_INCLUDE && 511 defined($function_table{$name}))) !! 586 defined($function_table{$name})) || >> 587 ($output_selection == OUTPUT_EXCLUDE && >> 588 !defined($function_table{$name}))) 512 { 589 { 513 dump_section($file, $name, $contents); !! 590 dump_section($file, $name, $contents); 514 output_blockhead({'sectionlist' => \@s !! 591 output_blockhead({'sectionlist' => \@sectionlist, 515 'sections' => \%sect !! 592 'sections' => \%sections, 516 'module' => $modulen !! 593 'module' => $modulename, 517 'content-only' => ($ !! 594 'content-only' => ($output_selection != OUTPUT_ALL), }); 518 } 595 } 519 } 596 } 520 597 521 ## 598 ## 522 # output function 599 # output function 523 # 600 # 524 # parameterdescs, a hash. 601 # parameterdescs, a hash. 525 # function => "function name" 602 # function => "function name" 526 # parameterlist => @list of parameters 603 # parameterlist => @list of parameters 527 # parameterdescs => %parameter descriptions 604 # parameterdescs => %parameter descriptions 528 # sectionlist => @list of sections 605 # sectionlist => @list of sections 529 # sections => %section descriptions 606 # sections => %section descriptions 530 # 607 # 531 608 532 sub output_highlight { 609 sub output_highlight { 533 my $contents = join "\n",@_; 610 my $contents = join "\n",@_; 534 my $line; 611 my $line; 535 612 536 # DEBUG 613 # DEBUG 537 # if (!defined $contents) { 614 # if (!defined $contents) { 538 # use Carp; 615 # use Carp; 539 # confess "output_highlight got called w 616 # confess "output_highlight got called with no args?\n"; 540 # } 617 # } 541 618 >> 619 if ($output_mode eq "html" || $output_mode eq "html5" || >> 620 $output_mode eq "xml") { >> 621 $contents = local_unescape($contents); >> 622 # convert data read & converted thru xml_escape() into &xyz; format: >> 623 $contents =~ s/\\\\\\/\&/g; >> 624 } 542 # print STDERR "contents b4:$contents\n"; 625 # print STDERR "contents b4:$contents\n"; 543 eval $dohighlight; 626 eval $dohighlight; 544 die $@ if $@; 627 die $@ if $@; 545 # print STDERR "contents af:$contents\n"; 628 # print STDERR "contents af:$contents\n"; 546 629 >> 630 # strip whitespaces when generating html5 >> 631 if ($output_mode eq "html5") { >> 632 $contents =~ s/^\s+//; >> 633 $contents =~ s/\s+$//; >> 634 } 547 foreach $line (split "\n", $contents) { 635 foreach $line (split "\n", $contents) { 548 if (! $output_preformatted) { !! 636 if (! $output_preformatted) { 549 $line =~ s/^\s*//; !! 637 $line =~ s/^\s*//; 550 } !! 638 } 551 if ($line eq ""){ !! 639 if ($line eq ""){ 552 if (! $output_preformatted) { !! 640 if (! $output_preformatted) { 553 print $lineprefix, $blankline; !! 641 print $lineprefix, local_unescape($blankline); 554 } !! 642 } 555 } else { !! 643 } else { 556 if ($output_mode eq "man" && subst !! 644 $line =~ s/\\\\\\/\&/g; 557 print "\\&$line"; !! 645 if ($output_mode eq "man" && substr($line, 0, 1) eq ".") { 558 } else { !! 646 print "\\&$line"; 559 print $lineprefix, $line; !! 647 } else { 560 } !! 648 print $lineprefix, $line; 561 } !! 649 } 562 print "\n"; !! 650 } >> 651 print "\n"; >> 652 } >> 653 } >> 654 >> 655 # output sections in html >> 656 sub output_section_html(%) { >> 657 my %args = %{$_[0]}; >> 658 my $section; >> 659 >> 660 foreach $section (@{$args{'sectionlist'}}) { >> 661 print "<h3>$section</h3>\n"; >> 662 print "<blockquote>\n"; >> 663 output_highlight($args{'sections'}{$section}); >> 664 print "</blockquote>\n"; >> 665 } >> 666 } >> 667 >> 668 # output enum in html >> 669 sub output_enum_html(%) { >> 670 my %args = %{$_[0]}; >> 671 my ($parameter); >> 672 my $count; >> 673 print "<h2>enum " . $args{'enum'} . "</h2>\n"; >> 674 >> 675 print "<b>enum " . $args{'enum'} . "</b> {<br>\n"; >> 676 $count = 0; >> 677 foreach $parameter (@{$args{'parameterlist'}}) { >> 678 print " <b>" . $parameter . "</b>"; >> 679 if ($count != $#{$args{'parameterlist'}}) { >> 680 $count++; >> 681 print ",\n"; >> 682 } >> 683 print "<br>"; >> 684 } >> 685 print "};<br>\n"; >> 686 >> 687 print "<h3>Constants</h3>\n"; >> 688 print "<dl>\n"; >> 689 foreach $parameter (@{$args{'parameterlist'}}) { >> 690 print "<dt><b>" . $parameter . "</b>\n"; >> 691 print "<dd>"; >> 692 output_highlight($args{'parameterdescs'}{$parameter}); >> 693 } >> 694 print "</dl>\n"; >> 695 output_section_html(@_); >> 696 print "<hr>\n"; >> 697 } >> 698 >> 699 # output typedef in html >> 700 sub output_typedef_html(%) { >> 701 my %args = %{$_[0]}; >> 702 my ($parameter); >> 703 my $count; >> 704 print "<h2>typedef " . $args{'typedef'} . "</h2>\n"; >> 705 >> 706 print "<b>typedef " . $args{'typedef'} . "</b>\n"; >> 707 output_section_html(@_); >> 708 print "<hr>\n"; >> 709 } >> 710 >> 711 # output struct in html >> 712 sub output_struct_html(%) { >> 713 my %args = %{$_[0]}; >> 714 my ($parameter); >> 715 >> 716 print "<h2>" . $args{'type'} . " " . $args{'struct'} . " - " . $args{'purpose'} . "</h2>\n"; >> 717 print "<b>" . $args{'type'} . " " . $args{'struct'} . "</b> {<br>\n"; >> 718 foreach $parameter (@{$args{'parameterlist'}}) { >> 719 if ($parameter =~ /^#/) { >> 720 print "$parameter<br>\n"; >> 721 next; >> 722 } >> 723 my $parameter_name = $parameter; >> 724 $parameter_name =~ s/\[.*//; >> 725 >> 726 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; >> 727 $type = $args{'parametertypes'}{$parameter}; >> 728 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { >> 729 # pointer-to-function >> 730 print " <i>$1</i><b>$parameter</b>) <i>($2)</i>;<br>\n"; >> 731 } elsif ($type =~ m/^(.*?)\s*(:.*)/) { >> 732 # bitfield >> 733 print " <i>$1</i> <b>$parameter</b>$2;<br>\n"; >> 734 } else { >> 735 print " <i>$type</i> <b>$parameter</b>;<br>\n"; >> 736 } >> 737 } >> 738 print "};<br>\n"; >> 739 >> 740 print "<h3>Members</h3>\n"; >> 741 print "<dl>\n"; >> 742 foreach $parameter (@{$args{'parameterlist'}}) { >> 743 ($parameter =~ /^#/) && next; >> 744 >> 745 my $parameter_name = $parameter; >> 746 $parameter_name =~ s/\[.*//; >> 747 >> 748 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; >> 749 print "<dt><b>" . $parameter . "</b>\n"; >> 750 print "<dd>"; >> 751 output_highlight($args{'parameterdescs'}{$parameter_name}); >> 752 } >> 753 print "</dl>\n"; >> 754 output_section_html(@_); >> 755 print "<hr>\n"; >> 756 } >> 757 >> 758 # output function in html >> 759 sub output_function_html(%) { >> 760 my %args = %{$_[0]}; >> 761 my ($parameter, $section); >> 762 my $count; >> 763 >> 764 print "<h2>" . $args{'function'} . " - " . $args{'purpose'} . "</h2>\n"; >> 765 print "<i>" . $args{'functiontype'} . "</i>\n"; >> 766 print "<b>" . $args{'function'} . "</b>\n"; >> 767 print "("; >> 768 $count = 0; >> 769 foreach $parameter (@{$args{'parameterlist'}}) { >> 770 $type = $args{'parametertypes'}{$parameter}; >> 771 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { >> 772 # pointer-to-function >> 773 print "<i>$1</i><b>$parameter</b>) <i>($2)</i>"; >> 774 } else { >> 775 print "<i>" . $type . "</i> <b>" . $parameter . "</b>"; >> 776 } >> 777 if ($count != $#{$args{'parameterlist'}}) { >> 778 $count++; >> 779 print ",\n"; >> 780 } >> 781 } >> 782 print ")\n"; >> 783 >> 784 print "<h3>Arguments</h3>\n"; >> 785 print "<dl>\n"; >> 786 foreach $parameter (@{$args{'parameterlist'}}) { >> 787 my $parameter_name = $parameter; >> 788 $parameter_name =~ s/\[.*//; >> 789 >> 790 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; >> 791 print "<dt><b>" . $parameter . "</b>\n"; >> 792 print "<dd>"; >> 793 output_highlight($args{'parameterdescs'}{$parameter_name}); >> 794 } >> 795 print "</dl>\n"; >> 796 output_section_html(@_); >> 797 print "<hr>\n"; >> 798 } >> 799 >> 800 # output DOC: block header in html >> 801 sub output_blockhead_html(%) { >> 802 my %args = %{$_[0]}; >> 803 my ($parameter, $section); >> 804 my $count; >> 805 >> 806 foreach $section (@{$args{'sectionlist'}}) { >> 807 print "<h3>$section</h3>\n"; >> 808 print "<ul>\n"; >> 809 output_highlight($args{'sections'}{$section}); >> 810 print "</ul>\n"; >> 811 } >> 812 print "<hr>\n"; >> 813 } >> 814 >> 815 # output sections in html5 >> 816 sub output_section_html5(%) { >> 817 my %args = %{$_[0]}; >> 818 my $section; >> 819 >> 820 foreach $section (@{$args{'sectionlist'}}) { >> 821 print "<section>\n"; >> 822 print "<h1>$section</h1>\n"; >> 823 print "<p>\n"; >> 824 output_highlight($args{'sections'}{$section}); >> 825 print "</p>\n"; >> 826 print "</section>\n"; >> 827 } >> 828 } >> 829 >> 830 # output enum in html5 >> 831 sub output_enum_html5(%) { >> 832 my %args = %{$_[0]}; >> 833 my ($parameter); >> 834 my $count; >> 835 my $html5id; >> 836 >> 837 $html5id = $args{'enum'}; >> 838 $html5id =~ s/[^a-zA-Z0-9\-]+/_/g; >> 839 print "<article class=\"enum\" id=\"enum:". $html5id . "\">"; >> 840 print "<h1>enum " . $args{'enum'} . "</h1>\n"; >> 841 print "<ol class=\"code\">\n"; >> 842 print "<li>"; >> 843 print "<span class=\"keyword\">enum</span> "; >> 844 print "<span class=\"identifier\">" . $args{'enum'} . "</span> {"; >> 845 print "</li>\n"; >> 846 $count = 0; >> 847 foreach $parameter (@{$args{'parameterlist'}}) { >> 848 print "<li class=\"indent\">"; >> 849 print "<span class=\"param\">" . $parameter . "</span>"; >> 850 if ($count != $#{$args{'parameterlist'}}) { >> 851 $count++; >> 852 print ","; >> 853 } >> 854 print "</li>\n"; >> 855 } >> 856 print "<li>};</li>\n"; >> 857 print "</ol>\n"; >> 858 >> 859 print "<section>\n"; >> 860 print "<h1>Constants</h1>\n"; >> 861 print "<dl>\n"; >> 862 foreach $parameter (@{$args{'parameterlist'}}) { >> 863 print "<dt>" . $parameter . "</dt>\n"; >> 864 print "<dd>"; >> 865 output_highlight($args{'parameterdescs'}{$parameter}); >> 866 print "</dd>\n"; >> 867 } >> 868 print "</dl>\n"; >> 869 print "</section>\n"; >> 870 output_section_html5(@_); >> 871 print "</article>\n"; >> 872 } >> 873 >> 874 # output typedef in html5 >> 875 sub output_typedef_html5(%) { >> 876 my %args = %{$_[0]}; >> 877 my ($parameter); >> 878 my $count; >> 879 my $html5id; >> 880 >> 881 $html5id = $args{'typedef'}; >> 882 $html5id =~ s/[^a-zA-Z0-9\-]+/_/g; >> 883 print "<article class=\"typedef\" id=\"typedef:" . $html5id . "\">\n"; >> 884 print "<h1>typedef " . $args{'typedef'} . "</h1>\n"; >> 885 >> 886 print "<ol class=\"code\">\n"; >> 887 print "<li>"; >> 888 print "<span class=\"keyword\">typedef</span> "; >> 889 print "<span class=\"identifier\">" . $args{'typedef'} . "</span>"; >> 890 print "</li>\n"; >> 891 print "</ol>\n"; >> 892 output_section_html5(@_); >> 893 print "</article>\n"; >> 894 } >> 895 >> 896 # output struct in html5 >> 897 sub output_struct_html5(%) { >> 898 my %args = %{$_[0]}; >> 899 my ($parameter); >> 900 my $html5id; >> 901 >> 902 $html5id = $args{'struct'}; >> 903 $html5id =~ s/[^a-zA-Z0-9\-]+/_/g; >> 904 print "<article class=\"struct\" id=\"struct:" . $html5id . "\">\n"; >> 905 print "<hgroup>\n"; >> 906 print "<h1>" . $args{'type'} . " " . $args{'struct'} . "</h1>"; >> 907 print "<h2>". $args{'purpose'} . "</h2>\n"; >> 908 print "</hgroup>\n"; >> 909 print "<ol class=\"code\">\n"; >> 910 print "<li>"; >> 911 print "<span class=\"type\">" . $args{'type'} . "</span> "; >> 912 print "<span class=\"identifier\">" . $args{'struct'} . "</span> {"; >> 913 print "</li>\n"; >> 914 foreach $parameter (@{$args{'parameterlist'}}) { >> 915 print "<li class=\"indent\">"; >> 916 if ($parameter =~ /^#/) { >> 917 print "<span class=\"param\">" . $parameter ."</span>\n"; >> 918 print "</li>\n"; >> 919 next; >> 920 } >> 921 my $parameter_name = $parameter; >> 922 $parameter_name =~ s/\[.*//; >> 923 >> 924 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; >> 925 $type = $args{'parametertypes'}{$parameter}; >> 926 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { >> 927 # pointer-to-function >> 928 print "<span class=\"type\">$1</span> "; >> 929 print "<span class=\"param\">$parameter</span>"; >> 930 print "<span class=\"type\">)</span> "; >> 931 print "(<span class=\"args\">$2</span>);"; >> 932 } elsif ($type =~ m/^(.*?)\s*(:.*)/) { >> 933 # bitfield >> 934 print "<span class=\"type\">$1</span> "; >> 935 print "<span class=\"param\">$parameter</span>"; >> 936 print "<span class=\"bits\">$2</span>;"; >> 937 } else { >> 938 print "<span class=\"type\">$type</span> "; >> 939 print "<span class=\"param\">$parameter</span>;"; >> 940 } >> 941 print "</li>\n"; >> 942 } >> 943 print "<li>};</li>\n"; >> 944 print "</ol>\n"; >> 945 >> 946 print "<section>\n"; >> 947 print "<h1>Members</h1>\n"; >> 948 print "<dl>\n"; >> 949 foreach $parameter (@{$args{'parameterlist'}}) { >> 950 ($parameter =~ /^#/) && next; >> 951 >> 952 my $parameter_name = $parameter; >> 953 $parameter_name =~ s/\[.*//; >> 954 >> 955 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; >> 956 print "<dt>" . $parameter . "</dt>\n"; >> 957 print "<dd>"; >> 958 output_highlight($args{'parameterdescs'}{$parameter_name}); >> 959 print "</dd>\n"; >> 960 } >> 961 print "</dl>\n"; >> 962 print "</section>\n"; >> 963 output_section_html5(@_); >> 964 print "</article>\n"; >> 965 } >> 966 >> 967 # output function in html5 >> 968 sub output_function_html5(%) { >> 969 my %args = %{$_[0]}; >> 970 my ($parameter, $section); >> 971 my $count; >> 972 my $html5id; >> 973 >> 974 $html5id = $args{'function'}; >> 975 $html5id =~ s/[^a-zA-Z0-9\-]+/_/g; >> 976 print "<article class=\"function\" id=\"func:". $html5id . "\">\n"; >> 977 print "<hgroup>\n"; >> 978 print "<h1>" . $args{'function'} . "</h1>"; >> 979 print "<h2>" . $args{'purpose'} . "</h2>\n"; >> 980 print "</hgroup>\n"; >> 981 print "<ol class=\"code\">\n"; >> 982 print "<li>"; >> 983 print "<span class=\"type\">" . $args{'functiontype'} . "</span> "; >> 984 print "<span class=\"identifier\">" . $args{'function'} . "</span> ("; >> 985 print "</li>"; >> 986 $count = 0; >> 987 foreach $parameter (@{$args{'parameterlist'}}) { >> 988 print "<li class=\"indent\">"; >> 989 $type = $args{'parametertypes'}{$parameter}; >> 990 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { >> 991 # pointer-to-function >> 992 print "<span class=\"type\">$1</span> "; >> 993 print "<span class=\"param\">$parameter</span>"; >> 994 print "<span class=\"type\">)</span> "; >> 995 print "(<span class=\"args\">$2</span>)"; >> 996 } else { >> 997 print "<span class=\"type\">$type</span> "; >> 998 print "<span class=\"param\">$parameter</span>"; >> 999 } >> 1000 if ($count != $#{$args{'parameterlist'}}) { >> 1001 $count++; >> 1002 print ","; >> 1003 } >> 1004 print "</li>\n"; >> 1005 } >> 1006 print "<li>)</li>\n"; >> 1007 print "</ol>\n"; >> 1008 >> 1009 print "<section>\n"; >> 1010 print "<h1>Arguments</h1>\n"; >> 1011 print "<p>\n"; >> 1012 print "<dl>\n"; >> 1013 foreach $parameter (@{$args{'parameterlist'}}) { >> 1014 my $parameter_name = $parameter; >> 1015 $parameter_name =~ s/\[.*//; >> 1016 >> 1017 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; >> 1018 print "<dt>" . $parameter . "</dt>\n"; >> 1019 print "<dd>"; >> 1020 output_highlight($args{'parameterdescs'}{$parameter_name}); >> 1021 print "</dd>\n"; >> 1022 } >> 1023 print "</dl>\n"; >> 1024 print "</section>\n"; >> 1025 output_section_html5(@_); >> 1026 print "</article>\n"; >> 1027 } >> 1028 >> 1029 # output DOC: block header in html5 >> 1030 sub output_blockhead_html5(%) { >> 1031 my %args = %{$_[0]}; >> 1032 my ($parameter, $section); >> 1033 my $count; >> 1034 my $html5id; >> 1035 >> 1036 foreach $section (@{$args{'sectionlist'}}) { >> 1037 $html5id = $section; >> 1038 $html5id =~ s/[^a-zA-Z0-9\-]+/_/g; >> 1039 print "<article class=\"doc\" id=\"doc:". $html5id . "\">\n"; >> 1040 print "<h1>$section</h1>\n"; >> 1041 print "<p>\n"; >> 1042 output_highlight($args{'sections'}{$section}); >> 1043 print "</p>\n"; >> 1044 } >> 1045 print "</article>\n"; >> 1046 } >> 1047 >> 1048 sub output_section_xml(%) { >> 1049 my %args = %{$_[0]}; >> 1050 my $section; >> 1051 # print out each section >> 1052 $lineprefix=" "; >> 1053 foreach $section (@{$args{'sectionlist'}}) { >> 1054 print "<refsect1>\n"; >> 1055 print "<title>$section</title>\n"; >> 1056 if ($section =~ m/EXAMPLE/i) { >> 1057 print "<informalexample><programlisting>\n"; >> 1058 $output_preformatted = 1; >> 1059 } else { >> 1060 print "<para>\n"; >> 1061 } >> 1062 output_highlight($args{'sections'}{$section}); >> 1063 $output_preformatted = 0; >> 1064 if ($section =~ m/EXAMPLE/i) { >> 1065 print "</programlisting></informalexample>\n"; >> 1066 } else { >> 1067 print "</para>\n"; >> 1068 } >> 1069 print "</refsect1>\n"; >> 1070 } >> 1071 } >> 1072 >> 1073 # output function in XML DocBook >> 1074 sub output_function_xml(%) { >> 1075 my %args = %{$_[0]}; >> 1076 my ($parameter, $section); >> 1077 my $count; >> 1078 my $id; >> 1079 >> 1080 $id = "API-" . $args{'function'}; >> 1081 $id =~ s/[^A-Za-z0-9]/-/g; >> 1082 >> 1083 print "<refentry id=\"$id\">\n"; >> 1084 print "<refentryinfo>\n"; >> 1085 print " <title>LINUX</title>\n"; >> 1086 print " <productname>Kernel Hackers Manual</productname>\n"; >> 1087 print " <date>$man_date</date>\n"; >> 1088 print "</refentryinfo>\n"; >> 1089 print "<refmeta>\n"; >> 1090 print " <refentrytitle><phrase>" . $args{'function'} . "</phrase></refentrytitle>\n"; >> 1091 print " <manvolnum>9</manvolnum>\n"; >> 1092 print " <refmiscinfo class=\"version\">" . $kernelversion . "</refmiscinfo>\n"; >> 1093 print "</refmeta>\n"; >> 1094 print "<refnamediv>\n"; >> 1095 print " <refname>" . $args{'function'} . "</refname>\n"; >> 1096 print " <refpurpose>\n"; >> 1097 print " "; >> 1098 output_highlight ($args{'purpose'}); >> 1099 print " </refpurpose>\n"; >> 1100 print "</refnamediv>\n"; >> 1101 >> 1102 print "<refsynopsisdiv>\n"; >> 1103 print " <title>Synopsis</title>\n"; >> 1104 print " <funcsynopsis><funcprototype>\n"; >> 1105 print " <funcdef>" . $args{'functiontype'} . " "; >> 1106 print "<function>" . $args{'function'} . " </function></funcdef>\n"; >> 1107 >> 1108 $count = 0; >> 1109 if ($#{$args{'parameterlist'}} >= 0) { >> 1110 foreach $parameter (@{$args{'parameterlist'}}) { >> 1111 $type = $args{'parametertypes'}{$parameter}; >> 1112 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { >> 1113 # pointer-to-function >> 1114 print " <paramdef>$1<parameter>$parameter</parameter>)\n"; >> 1115 print " <funcparams>$2</funcparams></paramdef>\n"; >> 1116 } else { >> 1117 print " <paramdef>" . $type; >> 1118 print " <parameter>$parameter</parameter></paramdef>\n"; >> 1119 } >> 1120 } >> 1121 } else { >> 1122 print " <void/>\n"; >> 1123 } >> 1124 print " </funcprototype></funcsynopsis>\n"; >> 1125 print "</refsynopsisdiv>\n"; >> 1126 >> 1127 # print parameters >> 1128 print "<refsect1>\n <title>Arguments</title>\n"; >> 1129 if ($#{$args{'parameterlist'}} >= 0) { >> 1130 print " <variablelist>\n"; >> 1131 foreach $parameter (@{$args{'parameterlist'}}) { >> 1132 my $parameter_name = $parameter; >> 1133 $parameter_name =~ s/\[.*//; >> 1134 >> 1135 print " <varlistentry>\n <term><parameter>$parameter</parameter></term>\n"; >> 1136 print " <listitem>\n <para>\n"; >> 1137 $lineprefix=" "; >> 1138 output_highlight($args{'parameterdescs'}{$parameter_name}); >> 1139 print " </para>\n </listitem>\n </varlistentry>\n"; >> 1140 } >> 1141 print " </variablelist>\n"; >> 1142 } else { >> 1143 print " <para>\n None\n </para>\n"; >> 1144 } >> 1145 print "</refsect1>\n"; >> 1146 >> 1147 output_section_xml(@_); >> 1148 print "</refentry>\n\n"; >> 1149 } >> 1150 >> 1151 # output struct in XML DocBook >> 1152 sub output_struct_xml(%) { >> 1153 my %args = %{$_[0]}; >> 1154 my ($parameter, $section); >> 1155 my $id; >> 1156 >> 1157 $id = "API-struct-" . $args{'struct'}; >> 1158 $id =~ s/[^A-Za-z0-9]/-/g; >> 1159 >> 1160 print "<refentry id=\"$id\">\n"; >> 1161 print "<refentryinfo>\n"; >> 1162 print " <title>LINUX</title>\n"; >> 1163 print " <productname>Kernel Hackers Manual</productname>\n"; >> 1164 print " <date>$man_date</date>\n"; >> 1165 print "</refentryinfo>\n"; >> 1166 print "<refmeta>\n"; >> 1167 print " <refentrytitle><phrase>" . $args{'type'} . " " . $args{'struct'} . "</phrase></refentrytitle>\n"; >> 1168 print " <manvolnum>9</manvolnum>\n"; >> 1169 print " <refmiscinfo class=\"version\">" . $kernelversion . "</refmiscinfo>\n"; >> 1170 print "</refmeta>\n"; >> 1171 print "<refnamediv>\n"; >> 1172 print " <refname>" . $args{'type'} . " " . $args{'struct'} . "</refname>\n"; >> 1173 print " <refpurpose>\n"; >> 1174 print " "; >> 1175 output_highlight ($args{'purpose'}); >> 1176 print " </refpurpose>\n"; >> 1177 print "</refnamediv>\n"; >> 1178 >> 1179 print "<refsynopsisdiv>\n"; >> 1180 print " <title>Synopsis</title>\n"; >> 1181 print " <programlisting>\n"; >> 1182 print $args{'type'} . " " . $args{'struct'} . " {\n"; >> 1183 foreach $parameter (@{$args{'parameterlist'}}) { >> 1184 if ($parameter =~ /^#/) { >> 1185 my $prm = $parameter; >> 1186 # convert data read & converted thru xml_escape() into &xyz; format: >> 1187 # This allows us to have #define macros interspersed in a struct. >> 1188 $prm =~ s/\\\\\\/\&/g; >> 1189 print "$prm\n"; >> 1190 next; >> 1191 } >> 1192 >> 1193 my $parameter_name = $parameter; >> 1194 $parameter_name =~ s/\[.*//; >> 1195 >> 1196 defined($args{'parameterdescs'}{$parameter_name}) || next; >> 1197 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; >> 1198 $type = $args{'parametertypes'}{$parameter}; >> 1199 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { >> 1200 # pointer-to-function >> 1201 print " $1 $parameter) ($2);\n"; >> 1202 } elsif ($type =~ m/^(.*?)\s*(:.*)/) { >> 1203 # bitfield >> 1204 print " $1 $parameter$2;\n"; >> 1205 } else { >> 1206 print " " . $type . " " . $parameter . ";\n"; >> 1207 } >> 1208 } >> 1209 print "};"; >> 1210 print " </programlisting>\n"; >> 1211 print "</refsynopsisdiv>\n"; >> 1212 >> 1213 print " <refsect1>\n"; >> 1214 print " <title>Members</title>\n"; >> 1215 >> 1216 if ($#{$args{'parameterlist'}} >= 0) { >> 1217 print " <variablelist>\n"; >> 1218 foreach $parameter (@{$args{'parameterlist'}}) { >> 1219 ($parameter =~ /^#/) && next; >> 1220 >> 1221 my $parameter_name = $parameter; >> 1222 $parameter_name =~ s/\[.*//; >> 1223 >> 1224 defined($args{'parameterdescs'}{$parameter_name}) || next; >> 1225 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; >> 1226 print " <varlistentry>"; >> 1227 print " <term>$parameter</term>\n"; >> 1228 print " <listitem><para>\n"; >> 1229 output_highlight($args{'parameterdescs'}{$parameter_name}); >> 1230 print " </para></listitem>\n"; >> 1231 print " </varlistentry>\n"; >> 1232 } >> 1233 print " </variablelist>\n"; >> 1234 } else { >> 1235 print " <para>\n None\n </para>\n"; >> 1236 } >> 1237 print " </refsect1>\n"; >> 1238 >> 1239 output_section_xml(@_); >> 1240 >> 1241 print "</refentry>\n\n"; >> 1242 } >> 1243 >> 1244 # output enum in XML DocBook >> 1245 sub output_enum_xml(%) { >> 1246 my %args = %{$_[0]}; >> 1247 my ($parameter, $section); >> 1248 my $count; >> 1249 my $id; >> 1250 >> 1251 $id = "API-enum-" . $args{'enum'}; >> 1252 $id =~ s/[^A-Za-z0-9]/-/g; >> 1253 >> 1254 print "<refentry id=\"$id\">\n"; >> 1255 print "<refentryinfo>\n"; >> 1256 print " <title>LINUX</title>\n"; >> 1257 print " <productname>Kernel Hackers Manual</productname>\n"; >> 1258 print " <date>$man_date</date>\n"; >> 1259 print "</refentryinfo>\n"; >> 1260 print "<refmeta>\n"; >> 1261 print " <refentrytitle><phrase>enum " . $args{'enum'} . "</phrase></refentrytitle>\n"; >> 1262 print " <manvolnum>9</manvolnum>\n"; >> 1263 print " <refmiscinfo class=\"version\">" . $kernelversion . "</refmiscinfo>\n"; >> 1264 print "</refmeta>\n"; >> 1265 print "<refnamediv>\n"; >> 1266 print " <refname>enum " . $args{'enum'} . "</refname>\n"; >> 1267 print " <refpurpose>\n"; >> 1268 print " "; >> 1269 output_highlight ($args{'purpose'}); >> 1270 print " </refpurpose>\n"; >> 1271 print "</refnamediv>\n"; >> 1272 >> 1273 print "<refsynopsisdiv>\n"; >> 1274 print " <title>Synopsis</title>\n"; >> 1275 print " <programlisting>\n"; >> 1276 print "enum " . $args{'enum'} . " {\n"; >> 1277 $count = 0; >> 1278 foreach $parameter (@{$args{'parameterlist'}}) { >> 1279 print " $parameter"; >> 1280 if ($count != $#{$args{'parameterlist'}}) { >> 1281 $count++; >> 1282 print ","; >> 1283 } >> 1284 print "\n"; >> 1285 } >> 1286 print "};"; >> 1287 print " </programlisting>\n"; >> 1288 print "</refsynopsisdiv>\n"; >> 1289 >> 1290 print "<refsect1>\n"; >> 1291 print " <title>Constants</title>\n"; >> 1292 print " <variablelist>\n"; >> 1293 foreach $parameter (@{$args{'parameterlist'}}) { >> 1294 my $parameter_name = $parameter; >> 1295 $parameter_name =~ s/\[.*//; >> 1296 >> 1297 print " <varlistentry>"; >> 1298 print " <term>$parameter</term>\n"; >> 1299 print " <listitem><para>\n"; >> 1300 output_highlight($args{'parameterdescs'}{$parameter_name}); >> 1301 print " </para></listitem>\n"; >> 1302 print " </varlistentry>\n"; >> 1303 } >> 1304 print " </variablelist>\n"; >> 1305 print "</refsect1>\n"; >> 1306 >> 1307 output_section_xml(@_); >> 1308 >> 1309 print "</refentry>\n\n"; >> 1310 } >> 1311 >> 1312 # output typedef in XML DocBook >> 1313 sub output_typedef_xml(%) { >> 1314 my %args = %{$_[0]}; >> 1315 my ($parameter, $section); >> 1316 my $id; >> 1317 >> 1318 $id = "API-typedef-" . $args{'typedef'}; >> 1319 $id =~ s/[^A-Za-z0-9]/-/g; >> 1320 >> 1321 print "<refentry id=\"$id\">\n"; >> 1322 print "<refentryinfo>\n"; >> 1323 print " <title>LINUX</title>\n"; >> 1324 print " <productname>Kernel Hackers Manual</productname>\n"; >> 1325 print " <date>$man_date</date>\n"; >> 1326 print "</refentryinfo>\n"; >> 1327 print "<refmeta>\n"; >> 1328 print " <refentrytitle><phrase>typedef " . $args{'typedef'} . "</phrase></refentrytitle>\n"; >> 1329 print " <manvolnum>9</manvolnum>\n"; >> 1330 print "</refmeta>\n"; >> 1331 print "<refnamediv>\n"; >> 1332 print " <refname>typedef " . $args{'typedef'} . "</refname>\n"; >> 1333 print " <refpurpose>\n"; >> 1334 print " "; >> 1335 output_highlight ($args{'purpose'}); >> 1336 print " </refpurpose>\n"; >> 1337 print "</refnamediv>\n"; >> 1338 >> 1339 print "<refsynopsisdiv>\n"; >> 1340 print " <title>Synopsis</title>\n"; >> 1341 print " <synopsis>typedef " . $args{'typedef'} . ";</synopsis>\n"; >> 1342 print "</refsynopsisdiv>\n"; >> 1343 >> 1344 output_section_xml(@_); >> 1345 >> 1346 print "</refentry>\n\n"; >> 1347 } >> 1348 >> 1349 # output in XML DocBook >> 1350 sub output_blockhead_xml(%) { >> 1351 my %args = %{$_[0]}; >> 1352 my ($parameter, $section); >> 1353 my $count; >> 1354 >> 1355 my $id = $args{'module'}; >> 1356 $id =~ s/[^A-Za-z0-9]/-/g; >> 1357 >> 1358 # print out each section >> 1359 $lineprefix=" "; >> 1360 foreach $section (@{$args{'sectionlist'}}) { >> 1361 if (!$args{'content-only'}) { >> 1362 print "<refsect1>\n <title>$section</title>\n"; >> 1363 } >> 1364 if ($section =~ m/EXAMPLE/i) { >> 1365 print "<example><para>\n"; >> 1366 $output_preformatted = 1; >> 1367 } else { >> 1368 print "<para>\n"; >> 1369 } >> 1370 output_highlight($args{'sections'}{$section}); >> 1371 $output_preformatted = 0; >> 1372 if ($section =~ m/EXAMPLE/i) { >> 1373 print "</para></example>\n"; >> 1374 } else { >> 1375 print "</para>"; >> 1376 } >> 1377 if (!$args{'content-only'}) { >> 1378 print "\n</refsect1>\n"; >> 1379 } 563 } 1380 } >> 1381 >> 1382 print "\n\n"; >> 1383 } >> 1384 >> 1385 # output in XML DocBook >> 1386 sub output_function_gnome { >> 1387 my %args = %{$_[0]}; >> 1388 my ($parameter, $section); >> 1389 my $count; >> 1390 my $id; >> 1391 >> 1392 $id = $args{'module'} . "-" . $args{'function'}; >> 1393 $id =~ s/[^A-Za-z0-9]/-/g; >> 1394 >> 1395 print "<sect2>\n"; >> 1396 print " <title id=\"$id\">" . $args{'function'} . "</title>\n"; >> 1397 >> 1398 print " <funcsynopsis>\n"; >> 1399 print " <funcdef>" . $args{'functiontype'} . " "; >> 1400 print "<function>" . $args{'function'} . " "; >> 1401 print "</function></funcdef>\n"; >> 1402 >> 1403 $count = 0; >> 1404 if ($#{$args{'parameterlist'}} >= 0) { >> 1405 foreach $parameter (@{$args{'parameterlist'}}) { >> 1406 $type = $args{'parametertypes'}{$parameter}; >> 1407 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { >> 1408 # pointer-to-function >> 1409 print " <paramdef>$1 <parameter>$parameter</parameter>)\n"; >> 1410 print " <funcparams>$2</funcparams></paramdef>\n"; >> 1411 } else { >> 1412 print " <paramdef>" . $type; >> 1413 print " <parameter>$parameter</parameter></paramdef>\n"; >> 1414 } >> 1415 } >> 1416 } else { >> 1417 print " <void>\n"; >> 1418 } >> 1419 print " </funcsynopsis>\n"; >> 1420 if ($#{$args{'parameterlist'}} >= 0) { >> 1421 print " <informaltable pgwide=\"1\" frame=\"none\" role=\"params\">\n"; >> 1422 print "<tgroup cols=\"2\">\n"; >> 1423 print "<colspec colwidth=\"2*\">\n"; >> 1424 print "<colspec colwidth=\"8*\">\n"; >> 1425 print "<tbody>\n"; >> 1426 foreach $parameter (@{$args{'parameterlist'}}) { >> 1427 my $parameter_name = $parameter; >> 1428 $parameter_name =~ s/\[.*//; >> 1429 >> 1430 print " <row><entry align=\"right\"><parameter>$parameter</parameter></entry>\n"; >> 1431 print " <entry>\n"; >> 1432 $lineprefix=" "; >> 1433 output_highlight($args{'parameterdescs'}{$parameter_name}); >> 1434 print " </entry></row>\n"; >> 1435 } >> 1436 print " </tbody></tgroup></informaltable>\n"; >> 1437 } else { >> 1438 print " <para>\n None\n </para>\n"; >> 1439 } >> 1440 >> 1441 # print out each section >> 1442 $lineprefix=" "; >> 1443 foreach $section (@{$args{'sectionlist'}}) { >> 1444 print "<simplesect>\n <title>$section</title>\n"; >> 1445 if ($section =~ m/EXAMPLE/i) { >> 1446 print "<example><programlisting>\n"; >> 1447 $output_preformatted = 1; >> 1448 } else { >> 1449 } >> 1450 print "<para>\n"; >> 1451 output_highlight($args{'sections'}{$section}); >> 1452 $output_preformatted = 0; >> 1453 print "</para>\n"; >> 1454 if ($section =~ m/EXAMPLE/i) { >> 1455 print "</programlisting></example>\n"; >> 1456 } else { >> 1457 } >> 1458 print " </simplesect>\n"; >> 1459 } >> 1460 >> 1461 print "</sect2>\n\n"; 564 } 1462 } 565 1463 566 ## 1464 ## 567 # output function in man 1465 # output function in man 568 sub output_function_man(%) { 1466 sub output_function_man(%) { 569 my %args = %{$_[0]}; 1467 my %args = %{$_[0]}; 570 my ($parameter, $section); 1468 my ($parameter, $section); 571 my $count; 1469 my $count; 572 1470 573 print ".TH \"$args{'function'}\" 9 \"$args 1471 print ".TH \"$args{'function'}\" 9 \"$args{'function'}\" \"$man_date\" \"Kernel Hacker's Manual\" LINUX\n"; 574 1472 575 print ".SH NAME\n"; 1473 print ".SH NAME\n"; 576 print $args{'function'} . " \\- " . $args{ 1474 print $args{'function'} . " \\- " . $args{'purpose'} . "\n"; 577 1475 578 print ".SH SYNOPSIS\n"; 1476 print ".SH SYNOPSIS\n"; 579 if ($args{'functiontype'} ne "") { 1477 if ($args{'functiontype'} ne "") { 580 print ".B \"" . $args{'functiontype'} !! 1478 print ".B \"" . $args{'functiontype'} . "\" " . $args{'function'} . "\n"; 581 } else { 1479 } else { 582 print ".B \"" . $args{'function'} . "\ !! 1480 print ".B \"" . $args{'function'} . "\n"; 583 } 1481 } 584 $count = 0; 1482 $count = 0; 585 my $parenth = "("; 1483 my $parenth = "("; 586 my $post = ","; 1484 my $post = ","; 587 foreach my $parameter (@{$args{'parameterl 1485 foreach my $parameter (@{$args{'parameterlist'}}) { 588 if ($count == $#{$args{'parameterlist' !! 1486 if ($count == $#{$args{'parameterlist'}}) { 589 $post = ");"; !! 1487 $post = ");"; 590 } !! 1488 } 591 $type = $args{'parametertypes'}{$param !! 1489 $type = $args{'parametertypes'}{$parameter}; 592 if ($type =~ m/$function_pointer/) { !! 1490 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { 593 # pointer-to-function !! 1491 # pointer-to-function 594 print ".BI \"" . $parenth . $1 . " !! 1492 print ".BI \"" . $parenth . $1 . "\" " . $parameter . " \") (" . $2 . ")" . $post . "\"\n"; 595 } else { !! 1493 } else { 596 $type =~ s/([^\*])$/$1 /; !! 1494 $type =~ s/([^\*])$/$1 /; 597 print ".BI \"" . $parenth . $type !! 1495 print ".BI \"" . $parenth . $type . "\" " . $parameter . " \"" . $post . "\"\n"; 598 } !! 1496 } 599 $count++; !! 1497 $count++; 600 $parenth = ""; !! 1498 $parenth = ""; 601 } 1499 } 602 1500 603 print ".SH ARGUMENTS\n"; 1501 print ".SH ARGUMENTS\n"; 604 foreach $parameter (@{$args{'parameterlist 1502 foreach $parameter (@{$args{'parameterlist'}}) { 605 my $parameter_name = $parameter; !! 1503 my $parameter_name = $parameter; 606 $parameter_name =~ s/\[.*//; !! 1504 $parameter_name =~ s/\[.*//; 607 1505 608 print ".IP \"" . $parameter . "\" 12\n !! 1506 print ".IP \"" . $parameter . "\" 12\n"; 609 output_highlight($args{'parameterdescs !! 1507 output_highlight($args{'parameterdescs'}{$parameter_name}); 610 } 1508 } 611 foreach $section (@{$args{'sectionlist'}}) 1509 foreach $section (@{$args{'sectionlist'}}) { 612 print ".SH \"", uc $section, "\"\n"; !! 1510 print ".SH \"", uc $section, "\"\n"; 613 output_highlight($args{'sections'}{$se !! 1511 output_highlight($args{'sections'}{$section}); 614 } 1512 } 615 } 1513 } 616 1514 617 ## 1515 ## 618 # output enum in man 1516 # output enum in man 619 sub output_enum_man(%) { 1517 sub output_enum_man(%) { 620 my %args = %{$_[0]}; 1518 my %args = %{$_[0]}; 621 my ($parameter, $section); 1519 my ($parameter, $section); 622 my $count; 1520 my $count; 623 1521 624 print ".TH \"$args{'module'}\" 9 \"enum $a 1522 print ".TH \"$args{'module'}\" 9 \"enum $args{'enum'}\" \"$man_date\" \"API Manual\" LINUX\n"; 625 1523 626 print ".SH NAME\n"; 1524 print ".SH NAME\n"; 627 print "enum " . $args{'enum'} . " \\- " . 1525 print "enum " . $args{'enum'} . " \\- " . $args{'purpose'} . "\n"; 628 1526 629 print ".SH SYNOPSIS\n"; 1527 print ".SH SYNOPSIS\n"; 630 print "enum " . $args{'enum'} . " {\n"; 1528 print "enum " . $args{'enum'} . " {\n"; 631 $count = 0; 1529 $count = 0; 632 foreach my $parameter (@{$args{'parameterl 1530 foreach my $parameter (@{$args{'parameterlist'}}) { 633 print ".br\n.BI \" $parameter\"\n"; !! 1531 print ".br\n.BI \" $parameter\"\n"; 634 if ($count == $#{$args{'parameterlist' !! 1532 if ($count == $#{$args{'parameterlist'}}) { 635 print "\n};\n"; !! 1533 print "\n};\n"; 636 last; !! 1534 last; 637 } else { !! 1535 } 638 print ", \n.br\n"; !! 1536 else { 639 } !! 1537 print ", \n.br\n"; 640 $count++; !! 1538 } >> 1539 $count++; 641 } 1540 } 642 1541 643 print ".SH Constants\n"; 1542 print ".SH Constants\n"; 644 foreach $parameter (@{$args{'parameterlist 1543 foreach $parameter (@{$args{'parameterlist'}}) { 645 my $parameter_name = $parameter; !! 1544 my $parameter_name = $parameter; 646 $parameter_name =~ s/\[.*//; !! 1545 $parameter_name =~ s/\[.*//; 647 1546 648 print ".IP \"" . $parameter . "\" 12\n !! 1547 print ".IP \"" . $parameter . "\" 12\n"; 649 output_highlight($args{'parameterdescs !! 1548 output_highlight($args{'parameterdescs'}{$parameter_name}); 650 } 1549 } 651 foreach $section (@{$args{'sectionlist'}}) 1550 foreach $section (@{$args{'sectionlist'}}) { 652 print ".SH \"$section\"\n"; !! 1551 print ".SH \"$section\"\n"; 653 output_highlight($args{'sections'}{$se !! 1552 output_highlight($args{'sections'}{$section}); 654 } 1553 } 655 } 1554 } 656 1555 657 ## 1556 ## 658 # output struct in man 1557 # output struct in man 659 sub output_struct_man(%) { 1558 sub output_struct_man(%) { 660 my %args = %{$_[0]}; 1559 my %args = %{$_[0]}; 661 my ($parameter, $section); 1560 my ($parameter, $section); 662 1561 663 print ".TH \"$args{'module'}\" 9 \"" . $ar 1562 print ".TH \"$args{'module'}\" 9 \"" . $args{'type'} . " " . $args{'struct'} . "\" \"$man_date\" \"API Manual\" LINUX\n"; 664 1563 665 print ".SH NAME\n"; 1564 print ".SH NAME\n"; 666 print $args{'type'} . " " . $args{'struct' 1565 print $args{'type'} . " " . $args{'struct'} . " \\- " . $args{'purpose'} . "\n"; 667 1566 668 my $declaration = $args{'definition'}; << 669 $declaration =~ s/\t/ /g; << 670 $declaration =~ s/\n/"\n.br\n.BI \"/g; << 671 print ".SH SYNOPSIS\n"; 1567 print ".SH SYNOPSIS\n"; 672 print $args{'type'} . " " . $args{'struct' 1568 print $args{'type'} . " " . $args{'struct'} . " {\n.br\n"; 673 print ".BI \"$declaration\n};\n.br\n\n"; !! 1569 >> 1570 foreach my $parameter (@{$args{'parameterlist'}}) { >> 1571 if ($parameter =~ /^#/) { >> 1572 print ".BI \"$parameter\"\n.br\n"; >> 1573 next; >> 1574 } >> 1575 my $parameter_name = $parameter; >> 1576 $parameter_name =~ s/\[.*//; >> 1577 >> 1578 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; >> 1579 $type = $args{'parametertypes'}{$parameter}; >> 1580 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { >> 1581 # pointer-to-function >> 1582 print ".BI \" " . $1 . "\" " . $parameter . " \") (" . $2 . ")" . "\"\n;\n"; >> 1583 } elsif ($type =~ m/^(.*?)\s*(:.*)/) { >> 1584 # bitfield >> 1585 print ".BI \" " . $1 . "\ \" " . $parameter . $2 . " \"" . "\"\n;\n"; >> 1586 } else { >> 1587 $type =~ s/([^\*])$/$1 /; >> 1588 print ".BI \" " . $type . "\" " . $parameter . " \"" . "\"\n;\n"; >> 1589 } >> 1590 print "\n.br\n"; >> 1591 } >> 1592 print "};\n.br\n"; 674 1593 675 print ".SH Members\n"; 1594 print ".SH Members\n"; 676 foreach $parameter (@{$args{'parameterlist 1595 foreach $parameter (@{$args{'parameterlist'}}) { 677 ($parameter =~ /^#/) && next; !! 1596 ($parameter =~ /^#/) && next; 678 1597 679 my $parameter_name = $parameter; !! 1598 my $parameter_name = $parameter; 680 $parameter_name =~ s/\[.*//; !! 1599 $parameter_name =~ s/\[.*//; 681 1600 682 ($args{'parameterdescs'}{$parameter_na !! 1601 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; 683 print ".IP \"" . $parameter . "\" 12\n !! 1602 print ".IP \"" . $parameter . "\" 12\n"; 684 output_highlight($args{'parameterdescs !! 1603 output_highlight($args{'parameterdescs'}{$parameter_name}); 685 } 1604 } 686 foreach $section (@{$args{'sectionlist'}}) 1605 foreach $section (@{$args{'sectionlist'}}) { 687 print ".SH \"$section\"\n"; !! 1606 print ".SH \"$section\"\n"; 688 output_highlight($args{'sections'}{$se !! 1607 output_highlight($args{'sections'}{$section}); 689 } 1608 } 690 } 1609 } 691 1610 692 ## 1611 ## 693 # output typedef in man 1612 # output typedef in man 694 sub output_typedef_man(%) { 1613 sub output_typedef_man(%) { 695 my %args = %{$_[0]}; 1614 my %args = %{$_[0]}; 696 my ($parameter, $section); 1615 my ($parameter, $section); 697 1616 698 print ".TH \"$args{'module'}\" 9 \"$args{' 1617 print ".TH \"$args{'module'}\" 9 \"$args{'typedef'}\" \"$man_date\" \"API Manual\" LINUX\n"; 699 1618 700 print ".SH NAME\n"; 1619 print ".SH NAME\n"; 701 print "typedef " . $args{'typedef'} . " \\ 1620 print "typedef " . $args{'typedef'} . " \\- " . $args{'purpose'} . "\n"; 702 1621 703 foreach $section (@{$args{'sectionlist'}}) 1622 foreach $section (@{$args{'sectionlist'}}) { 704 print ".SH \"$section\"\n"; !! 1623 print ".SH \"$section\"\n"; 705 output_highlight($args{'sections'}{$se !! 1624 output_highlight($args{'sections'}{$section}); 706 } 1625 } 707 } 1626 } 708 1627 709 sub output_blockhead_man(%) { 1628 sub output_blockhead_man(%) { 710 my %args = %{$_[0]}; 1629 my %args = %{$_[0]}; 711 my ($parameter, $section); 1630 my ($parameter, $section); 712 my $count; 1631 my $count; 713 1632 714 print ".TH \"$args{'module'}\" 9 \"$args{' 1633 print ".TH \"$args{'module'}\" 9 \"$args{'module'}\" \"$man_date\" \"API Manual\" LINUX\n"; 715 1634 716 foreach $section (@{$args{'sectionlist'}}) 1635 foreach $section (@{$args{'sectionlist'}}) { 717 print ".SH \"$section\"\n"; !! 1636 print ".SH \"$section\"\n"; 718 output_highlight($args{'sections'}{$se !! 1637 output_highlight($args{'sections'}{$section}); >> 1638 } >> 1639 } >> 1640 >> 1641 ## >> 1642 # output in text >> 1643 sub output_function_text(%) { >> 1644 my %args = %{$_[0]}; >> 1645 my ($parameter, $section); >> 1646 my $start; >> 1647 >> 1648 print "Name:\n\n"; >> 1649 print $args{'function'} . " - " . $args{'purpose'} . "\n"; >> 1650 >> 1651 print "\nSynopsis:\n\n"; >> 1652 if ($args{'functiontype'} ne "") { >> 1653 $start = $args{'functiontype'} . " " . $args{'function'} . " ("; >> 1654 } else { >> 1655 $start = $args{'function'} . " ("; >> 1656 } >> 1657 print $start; >> 1658 >> 1659 my $count = 0; >> 1660 foreach my $parameter (@{$args{'parameterlist'}}) { >> 1661 $type = $args{'parametertypes'}{$parameter}; >> 1662 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { >> 1663 # pointer-to-function >> 1664 print $1 . $parameter . ") (" . $2; >> 1665 } else { >> 1666 print $type . " " . $parameter; >> 1667 } >> 1668 if ($count != $#{$args{'parameterlist'}}) { >> 1669 $count++; >> 1670 print ",\n"; >> 1671 print " " x length($start); >> 1672 } else { >> 1673 print ");\n\n"; >> 1674 } >> 1675 } >> 1676 >> 1677 print "Arguments:\n\n"; >> 1678 foreach $parameter (@{$args{'parameterlist'}}) { >> 1679 my $parameter_name = $parameter; >> 1680 $parameter_name =~ s/\[.*//; >> 1681 >> 1682 print $parameter . "\n\t" . $args{'parameterdescs'}{$parameter_name} . "\n"; >> 1683 } >> 1684 output_section_text(@_); >> 1685 } >> 1686 >> 1687 #output sections in text >> 1688 sub output_section_text(%) { >> 1689 my %args = %{$_[0]}; >> 1690 my $section; >> 1691 >> 1692 print "\n"; >> 1693 foreach $section (@{$args{'sectionlist'}}) { >> 1694 print "$section:\n\n"; >> 1695 output_highlight($args{'sections'}{$section}); >> 1696 } >> 1697 print "\n\n"; >> 1698 } >> 1699 >> 1700 # output enum in text >> 1701 sub output_enum_text(%) { >> 1702 my %args = %{$_[0]}; >> 1703 my ($parameter); >> 1704 my $count; >> 1705 print "Enum:\n\n"; >> 1706 >> 1707 print "enum " . $args{'enum'} . " - " . $args{'purpose'} . "\n\n"; >> 1708 print "enum " . $args{'enum'} . " {\n"; >> 1709 $count = 0; >> 1710 foreach $parameter (@{$args{'parameterlist'}}) { >> 1711 print "\t$parameter"; >> 1712 if ($count != $#{$args{'parameterlist'}}) { >> 1713 $count++; >> 1714 print ","; >> 1715 } >> 1716 print "\n"; >> 1717 } >> 1718 print "};\n\n"; >> 1719 >> 1720 print "Constants:\n\n"; >> 1721 foreach $parameter (@{$args{'parameterlist'}}) { >> 1722 print "$parameter\n\t"; >> 1723 print $args{'parameterdescs'}{$parameter} . "\n"; >> 1724 } >> 1725 >> 1726 output_section_text(@_); >> 1727 } >> 1728 >> 1729 # output typedef in text >> 1730 sub output_typedef_text(%) { >> 1731 my %args = %{$_[0]}; >> 1732 my ($parameter); >> 1733 my $count; >> 1734 print "Typedef:\n\n"; >> 1735 >> 1736 print "typedef " . $args{'typedef'} . " - " . $args{'purpose'} . "\n"; >> 1737 output_section_text(@_); >> 1738 } >> 1739 >> 1740 # output struct as text >> 1741 sub output_struct_text(%) { >> 1742 my %args = %{$_[0]}; >> 1743 my ($parameter); >> 1744 >> 1745 print $args{'type'} . " " . $args{'struct'} . " - " . $args{'purpose'} . "\n\n"; >> 1746 print $args{'type'} . " " . $args{'struct'} . " {\n"; >> 1747 foreach $parameter (@{$args{'parameterlist'}}) { >> 1748 if ($parameter =~ /^#/) { >> 1749 print "$parameter\n"; >> 1750 next; >> 1751 } >> 1752 >> 1753 my $parameter_name = $parameter; >> 1754 $parameter_name =~ s/\[.*//; >> 1755 >> 1756 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; >> 1757 $type = $args{'parametertypes'}{$parameter}; >> 1758 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { >> 1759 # pointer-to-function >> 1760 print "\t$1 $parameter) ($2);\n"; >> 1761 } elsif ($type =~ m/^(.*?)\s*(:.*)/) { >> 1762 # bitfield >> 1763 print "\t$1 $parameter$2;\n"; >> 1764 } else { >> 1765 print "\t" . $type . " " . $parameter . ";\n"; >> 1766 } >> 1767 } >> 1768 print "};\n\n"; >> 1769 >> 1770 print "Members:\n\n"; >> 1771 foreach $parameter (@{$args{'parameterlist'}}) { >> 1772 ($parameter =~ /^#/) && next; >> 1773 >> 1774 my $parameter_name = $parameter; >> 1775 $parameter_name =~ s/\[.*//; >> 1776 >> 1777 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; >> 1778 print "$parameter\n\t"; >> 1779 print $args{'parameterdescs'}{$parameter_name} . "\n"; >> 1780 } >> 1781 print "\n"; >> 1782 output_section_text(@_); >> 1783 } >> 1784 >> 1785 sub output_blockhead_text(%) { >> 1786 my %args = %{$_[0]}; >> 1787 my ($parameter, $section); >> 1788 >> 1789 foreach $section (@{$args{'sectionlist'}}) { >> 1790 print " $section:\n"; >> 1791 print " -> "; >> 1792 output_highlight($args{'sections'}{$section}); 719 } 1793 } 720 } 1794 } 721 1795 722 ## 1796 ## 723 # output in restructured text 1797 # output in restructured text 724 # 1798 # 725 1799 726 # 1800 # 727 # This could use some work; it's used to outpu 1801 # 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 1802 # starts by putting out the name of the doc section itself, but that tends 729 # to duplicate a header already in the templat 1803 # to duplicate a header already in the template file. 730 # 1804 # 731 sub output_blockhead_rst(%) { 1805 sub output_blockhead_rst(%) { 732 my %args = %{$_[0]}; 1806 my %args = %{$_[0]}; 733 my ($parameter, $section); 1807 my ($parameter, $section); 734 1808 735 foreach $section (@{$args{'sectionlist'}}) 1809 foreach $section (@{$args{'sectionlist'}}) { 736 next if (defined($nosymbol_table{$sect !! 1810 if ($output_selection != OUTPUT_INCLUDE) { 737 !! 1811 print "**$section**\n\n"; 738 if ($output_selection != OUTPUT_INCLUD !! 1812 } 739 print ".. _$section:\n\n"; << 740 print "**$section**\n\n"; << 741 } << 742 print_lineno($section_start_lines{$sec 1813 print_lineno($section_start_lines{$section}); 743 output_highlight_rst($args{'sections'} !! 1814 output_highlight_rst($args{'sections'}{$section}); 744 print "\n"; !! 1815 print "\n"; 745 } 1816 } 746 } 1817 } 747 1818 748 # << 749 # Apply the RST highlights to a sub-block of t << 750 # << 751 sub highlight_block($) { << 752 # The dohighlight kludge requires the text << 753 my $contents = shift; << 754 eval $dohighlight; << 755 die $@ if $@; << 756 return $contents; << 757 } << 758 << 759 # << 760 # Regexes used only here. << 761 # << 762 my $sphinx_literal = '^[^.].*::$'; << 763 my $sphinx_cblock = '^\.\.\ +code-block::'; << 764 << 765 sub output_highlight_rst { 1819 sub output_highlight_rst { 766 my $input = join "\n",@_; !! 1820 my $contents = join "\n",@_; 767 my $output = ""; << 768 my $line; 1821 my $line; 769 my $in_literal = 0; << 770 my $litprefix; << 771 my $block = ""; << 772 << 773 foreach $line (split "\n",$input) { << 774 # << 775 # If we're in a literal block, see if << 776 # of it. Otherwise pass the line stra << 777 # << 778 if ($in_literal) { << 779 if (! ($line =~ /^\s*$/)) { << 780 # << 781 # If this is the first non-bla << 782 # block we need to figure out << 783 # << 784 if ($litprefix eq "") { << 785 $line =~ /^(\s*)/; << 786 $litprefix = '^' . $1; << 787 $output .= $line . "\n"; << 788 } elsif (! ($line =~ /$litpref << 789 $in_literal = 0; << 790 } else { << 791 $output .= $line . "\n"; << 792 } << 793 } else { << 794 $output .= $line . "\n"; << 795 } << 796 } << 797 # << 798 # Not in a literal block (or just drop << 799 # << 800 if (! $in_literal) { << 801 $block .= $line . "\n"; << 802 if (($line =~ /$sphinx_literal/) | << 803 $in_literal = 1; << 804 $litprefix = ""; << 805 $output .= highlight_block($bl << 806 $block = "" << 807 } << 808 } << 809 } << 810 1822 811 if ($block) { !! 1823 # undo the evil effects of xml_escape() earlier 812 $output .= highlight_block($block); !! 1824 $contents = xml_unescape($contents); 813 } !! 1825 814 foreach $line (split "\n", $output) { !! 1826 eval $dohighlight; 815 print $lineprefix . $line . "\n"; !! 1827 die $@ if $@; >> 1828 >> 1829 foreach $line (split "\n", $contents) { >> 1830 print $lineprefix . $line . "\n"; 816 } 1831 } 817 } 1832 } 818 1833 819 sub output_function_rst(%) { 1834 sub output_function_rst(%) { 820 my %args = %{$_[0]}; 1835 my %args = %{$_[0]}; 821 my ($parameter, $section); 1836 my ($parameter, $section); 822 my $oldprefix = $lineprefix; 1837 my $oldprefix = $lineprefix; >> 1838 my $start = ""; 823 1839 824 my $signature = ""; !! 1840 if ($args{'typedef'}) { >> 1841 print ".. c:type:: ". $args{'function'} . "\n\n"; >> 1842 print_lineno($declaration_start_line); >> 1843 print " **Typedef**: "; >> 1844 $lineprefix = ""; >> 1845 output_highlight_rst($args{'purpose'}); >> 1846 $start = "\n\n**Syntax**\n\n ``"; >> 1847 } else { >> 1848 print ".. c:function:: "; >> 1849 } 825 if ($args{'functiontype'} ne "") { 1850 if ($args{'functiontype'} ne "") { 826 $signature = $args{'functiontype'} . " !! 1851 $start .= $args{'functiontype'} . " " . $args{'function'} . " ("; 827 } else { 1852 } else { 828 $signature = $args{'function'} . " ("; !! 1853 $start .= $args{'function'} . " ("; 829 } 1854 } >> 1855 print $start; 830 1856 831 my $count = 0; 1857 my $count = 0; 832 foreach my $parameter (@{$args{'parameterl 1858 foreach my $parameter (@{$args{'parameterlist'}}) { 833 if ($count ne 0) { !! 1859 if ($count ne 0) { 834 $signature .= ", "; !! 1860 print ", "; 835 } !! 1861 } 836 $count++; !! 1862 $count++; 837 $type = $args{'parametertypes'}{$param !! 1863 $type = $args{'parametertypes'}{$parameter}; 838 !! 1864 839 if ($type =~ m/$function_pointer/) { !! 1865 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { 840 # pointer-to-function !! 1866 # pointer-to-function 841 $signature .= $1 . $parameter . ") !! 1867 print $1 . $parameter . ") (" . $2; 842 } else { !! 1868 } else { 843 $signature .= $type; !! 1869 print $type . " " . $parameter; 844 } !! 1870 } 845 } 1871 } 846 !! 1872 if ($args{'typedef'}) { 847 $signature .= ")"; !! 1873 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 { 1874 } else { 862 if ($args{'typedef'} || $args{'functio !! 1875 print ")\n\n"; 863 print ".. c:macro:: ". $args{'func !! 1876 print_lineno($declaration_start_line); 864 !! 1877 $lineprefix = " "; 865 if ($args{'typedef'}) { !! 1878 output_highlight_rst($args{'purpose'}); 866 print_lineno($declaration_star !! 1879 print "\n"; 867 print " **Typedef**: "; << 868 $lineprefix = ""; << 869 output_highlight_rst($args{'pu << 870 print "\n\n**Syntax**\n\n"; << 871 print " ``$signature``\n\n"; << 872 } else { << 873 print "``$signature``\n\n"; << 874 } << 875 } else { << 876 print ".. c:function:: $signature\ << 877 } << 878 } << 879 << 880 if (!$args{'typedef'}) { << 881 print_lineno($declaration_start_line); << 882 $lineprefix = " "; << 883 output_highlight_rst($args{'purpose'}) << 884 print "\n"; << 885 } 1880 } 886 1881 887 # !! 1882 print "**Parameters**\n\n"; 888 # Put our descriptive text into a containe << 889 # set the function prototypes apart. << 890 # << 891 print ".. container:: kernelindent\n\n"; << 892 $lineprefix = " "; 1883 $lineprefix = " "; 893 print $lineprefix . "**Parameters**\n\n"; << 894 foreach $parameter (@{$args{'parameterlist 1884 foreach $parameter (@{$args{'parameterlist'}}) { 895 my $parameter_name = $parameter; !! 1885 my $parameter_name = $parameter; 896 $parameter_name =~ s/\[.*//; !! 1886 #$parameter_name =~ s/\[.*//; 897 $type = $args{'parametertypes'}{$param !! 1887 $type = $args{'parametertypes'}{$parameter}; 898 !! 1888 899 if ($type ne "") { !! 1889 if ($type ne "") { 900 print $lineprefix . "``$type``\n"; !! 1890 print "``$type $parameter``\n"; 901 } else { !! 1891 } else { 902 print $lineprefix . "``$parameter` !! 1892 print "``$parameter``\n"; 903 } !! 1893 } 904 1894 905 print_lineno($parameterdesc_start_line 1895 print_lineno($parameterdesc_start_lines{$parameter_name}); 906 1896 907 $lineprefix = " "; !! 1897 if (defined($args{'parameterdescs'}{$parameter_name}) && 908 if (defined($args{'parameterdescs'}{$p !! 1898 $args{'parameterdescs'}{$parameter_name} ne $undescribed) { 909 $args{'parameterdescs'}{$parameter !! 1899 output_highlight_rst($args{'parameterdescs'}{$parameter_name}); 910 output_highlight_rst($args{'parame !! 1900 } else { 911 } else { !! 1901 print " *undescribed*\n"; 912 print $lineprefix . "*undescribed* !! 1902 } 913 } !! 1903 print "\n"; 914 $lineprefix = " "; << 915 print "\n"; << 916 } 1904 } 917 1905 918 output_section_rst(@_); << 919 $lineprefix = $oldprefix; 1906 $lineprefix = $oldprefix; >> 1907 output_section_rst(@_); 920 } 1908 } 921 1909 922 sub output_section_rst(%) { 1910 sub output_section_rst(%) { 923 my %args = %{$_[0]}; 1911 my %args = %{$_[0]}; 924 my $section; 1912 my $section; 925 my $oldprefix = $lineprefix; 1913 my $oldprefix = $lineprefix; >> 1914 $lineprefix = ""; 926 1915 927 foreach $section (@{$args{'sectionlist'}}) 1916 foreach $section (@{$args{'sectionlist'}}) { 928 print $lineprefix . "**$section**\n\n" !! 1917 print "**$section**\n\n"; 929 print_lineno($section_start_lines{$sec 1918 print_lineno($section_start_lines{$section}); 930 output_highlight_rst($args{'sections'} !! 1919 output_highlight_rst($args{'sections'}{$section}); 931 print "\n"; !! 1920 print "\n"; 932 } 1921 } 933 print "\n"; 1922 print "\n"; >> 1923 $lineprefix = $oldprefix; 934 } 1924 } 935 1925 936 sub output_enum_rst(%) { 1926 sub output_enum_rst(%) { 937 my %args = %{$_[0]}; 1927 my %args = %{$_[0]}; 938 my ($parameter); 1928 my ($parameter); 939 my $oldprefix = $lineprefix; 1929 my $oldprefix = $lineprefix; 940 my $count; 1930 my $count; 941 my $outer; !! 1931 my $name = "enum " . $args{'enum'}; 942 1932 943 if ($sphinx_major < 3) { !! 1933 print "\n\n.. c:type:: " . $name . "\n\n"; 944 my $name = "enum " . $args{'enum'}; << 945 print "\n\n.. c:type:: " . $name . "\n << 946 } else { << 947 my $name = $args{'enum'}; << 948 print "\n\n.. c:enum:: " . $name . "\n << 949 } << 950 print_lineno($declaration_start_line); 1934 print_lineno($declaration_start_line); 951 $lineprefix = " "; !! 1935 $lineprefix = " "; 952 output_highlight_rst($args{'purpose'}); 1936 output_highlight_rst($args{'purpose'}); 953 print "\n"; 1937 print "\n"; 954 1938 955 print ".. container:: kernelindent\n\n"; !! 1939 print "**Constants**\n\n"; 956 $outer = $lineprefix . " "; !! 1940 $lineprefix = " "; 957 $lineprefix = $outer . " "; !! 1941 foreach $parameter (@{$args{'parameterlist'}}) { 958 print $outer . "**Constants**\n\n"; !! 1942 print "``$parameter``\n"; 959 foreach $parameter (@{$args{'parameterlist !! 1943 if ($args{'parameterdescs'}{$parameter} ne $undescribed) { 960 print $outer . "``$parameter``\n"; !! 1944 output_highlight_rst($args{'parameterdescs'}{$parameter}); 961 !! 1945 } else { 962 if ($args{'parameterdescs'}{$parameter !! 1946 print " *undescribed*\n"; 963 output_highlight_rst($args{'parame !! 1947 } 964 } else { !! 1948 print "\n"; 965 print $lineprefix . "*undescribed* << 966 } << 967 print "\n"; << 968 } 1949 } 969 print "\n"; !! 1950 970 $lineprefix = $oldprefix; 1951 $lineprefix = $oldprefix; 971 output_section_rst(@_); 1952 output_section_rst(@_); 972 } 1953 } 973 1954 974 sub output_typedef_rst(%) { 1955 sub output_typedef_rst(%) { 975 my %args = %{$_[0]}; 1956 my %args = %{$_[0]}; 976 my ($parameter); 1957 my ($parameter); 977 my $oldprefix = $lineprefix; 1958 my $oldprefix = $lineprefix; 978 my $name; !! 1959 my $name = "typedef " . $args{'typedef'}; 979 1960 980 if ($sphinx_major < 3) { << 981 $name = "typedef " . $args{'typedef'}; << 982 } else { << 983 $name = $args{'typedef'}; << 984 } << 985 print "\n\n.. c:type:: " . $name . "\n\n"; 1961 print "\n\n.. c:type:: " . $name . "\n\n"; 986 print_lineno($declaration_start_line); 1962 print_lineno($declaration_start_line); 987 $lineprefix = " "; 1963 $lineprefix = " "; 988 output_highlight_rst($args{'purpose'}); 1964 output_highlight_rst($args{'purpose'}); 989 print "\n"; 1965 print "\n"; 990 1966 991 $lineprefix = $oldprefix; 1967 $lineprefix = $oldprefix; 992 output_section_rst(@_); 1968 output_section_rst(@_); 993 } 1969 } 994 1970 995 sub output_struct_rst(%) { 1971 sub output_struct_rst(%) { 996 my %args = %{$_[0]}; 1972 my %args = %{$_[0]}; 997 my ($parameter); 1973 my ($parameter); 998 my $oldprefix = $lineprefix; 1974 my $oldprefix = $lineprefix; >> 1975 my $name = $args{'type'} . " " . $args{'struct'}; 999 1976 1000 if ($sphinx_major < 3) { !! 1977 print "\n\n.. c:type:: " . $name . "\n\n"; 1001 my $name = $args{'type'} . " " . $arg << 1002 print "\n\n.. c:type:: " . $name . "\ << 1003 } else { << 1004 my $name = $args{'struct'}; << 1005 if ($args{'type'} eq 'union') { << 1006 print "\n\n.. c:union:: " . $name << 1007 } else { << 1008 print "\n\n.. c:struct:: " . $nam << 1009 } << 1010 } << 1011 print_lineno($declaration_start_line); 1978 print_lineno($declaration_start_line); 1012 $lineprefix = " "; !! 1979 $lineprefix = " "; 1013 output_highlight_rst($args{'purpose'}); 1980 output_highlight_rst($args{'purpose'}); 1014 print "\n"; 1981 print "\n"; 1015 1982 1016 print ".. container:: kernelindent\n\n"; !! 1983 print "**Definition**\n\n"; 1017 print $lineprefix . "**Definition**::\n\n !! 1984 print "::\n\n"; 1018 my $declaration = $args{'definition'}; !! 1985 print " " . $args{'type'} . " " . $args{'struct'} . " {\n"; 1019 $lineprefix = $lineprefix . " "; !! 1986 foreach $parameter (@{$args{'parameterlist'}}) { 1020 $declaration =~ s/\t/$lineprefix/g; !! 1987 if ($parameter =~ /^#/) { 1021 print $lineprefix . $args{'type'} . " " . !! 1988 print " " . "$parameter\n"; >> 1989 next; >> 1990 } >> 1991 >> 1992 my $parameter_name = $parameter; >> 1993 $parameter_name =~ s/\[.*//; >> 1994 >> 1995 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; >> 1996 $type = $args{'parametertypes'}{$parameter}; >> 1997 if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { >> 1998 # pointer-to-function >> 1999 print " $1 $parameter) ($2);\n"; >> 2000 } elsif ($type =~ m/^(.*?)\s*(:.*)/) { >> 2001 # bitfield >> 2002 print " $1 $parameter$2;\n"; >> 2003 } else { >> 2004 print " " . $type . " " . $parameter . ";\n"; >> 2005 } >> 2006 } >> 2007 print " };\n\n"; 1022 2008 >> 2009 print "**Members**\n\n"; 1023 $lineprefix = " "; 2010 $lineprefix = " "; 1024 print $lineprefix . "**Members**\n\n"; << 1025 foreach $parameter (@{$args{'parameterlis 2011 foreach $parameter (@{$args{'parameterlist'}}) { 1026 ($parameter =~ /^#/) && next; !! 2012 ($parameter =~ /^#/) && next; 1027 2013 1028 my $parameter_name = $parameter; !! 2014 my $parameter_name = $parameter; 1029 $parameter_name =~ s/\[.*//; !! 2015 $parameter_name =~ s/\[.*//; 1030 2016 1031 ($args{'parameterdescs'}{$parameter_n !! 2017 ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; 1032 $type = $args{'parametertypes'}{$para !! 2018 $type = $args{'parametertypes'}{$parameter}; 1033 print_lineno($parameterdesc_start_lin 2019 print_lineno($parameterdesc_start_lines{$parameter_name}); 1034 print $lineprefix . "``" . $parameter !! 2020 print "``" . $parameter . "``\n"; 1035 $lineprefix = " "; !! 2021 output_highlight_rst($args{'parameterdescs'}{$parameter_name}); 1036 output_highlight_rst($args{'parameter !! 2022 print "\n"; 1037 $lineprefix = " "; << 1038 print "\n"; << 1039 } 2023 } 1040 print "\n"; 2024 print "\n"; 1041 2025 1042 $lineprefix = $oldprefix; 2026 $lineprefix = $oldprefix; 1043 output_section_rst(@_); 2027 output_section_rst(@_); 1044 } 2028 } 1045 2029 1046 ## none mode output functions << 1047 2030 1048 sub output_function_none(%) { !! 2031 ## list mode output functions >> 2032 >> 2033 sub output_function_list(%) { >> 2034 my %args = %{$_[0]}; >> 2035 >> 2036 print $args{'function'} . "\n"; 1049 } 2037 } 1050 2038 1051 sub output_enum_none(%) { !! 2039 # output enum in list >> 2040 sub output_enum_list(%) { >> 2041 my %args = %{$_[0]}; >> 2042 print $args{'enum'} . "\n"; 1052 } 2043 } 1053 2044 1054 sub output_typedef_none(%) { !! 2045 # output typedef in list >> 2046 sub output_typedef_list(%) { >> 2047 my %args = %{$_[0]}; >> 2048 print $args{'typedef'} . "\n"; 1055 } 2049 } 1056 2050 1057 sub output_struct_none(%) { !! 2051 # output struct as list >> 2052 sub output_struct_list(%) { >> 2053 my %args = %{$_[0]}; >> 2054 >> 2055 print $args{'struct'} . "\n"; 1058 } 2056 } 1059 2057 1060 sub output_blockhead_none(%) { !! 2058 sub output_blockhead_list(%) { >> 2059 my %args = %{$_[0]}; >> 2060 my ($parameter, $section); >> 2061 >> 2062 foreach $section (@{$args{'sectionlist'}}) { >> 2063 print "DOC: $section\n"; >> 2064 } 1061 } 2065 } 1062 2066 1063 ## 2067 ## 1064 # generic output function for all types (func 2068 # generic output function for all types (function, struct/union, typedef, enum); 1065 # calls the generated, variable output_ funct 2069 # calls the generated, variable output_ function name based on 1066 # functype and output_mode 2070 # functype and output_mode 1067 sub output_declaration { 2071 sub output_declaration { 1068 no strict 'refs'; 2072 no strict 'refs'; 1069 my $name = shift; 2073 my $name = shift; 1070 my $functype = shift; 2074 my $functype = shift; 1071 my $func = "output_${functype}_$output_mo 2075 my $func = "output_${functype}_$output_mode"; 1072 << 1073 return if (defined($nosymbol_table{$name} << 1074 << 1075 if (($output_selection == OUTPUT_ALL) || 2076 if (($output_selection == OUTPUT_ALL) || 1076 (($output_selection == OUTPUT_INCLUDE !! 2077 (($output_selection == OUTPUT_INCLUDE || 1077 $output_selection == OUTPUT_EXPORTE !! 2078 $output_selection == OUTPUT_EXPORTED) && 1078 defined($function_table{$name})) || !! 2079 defined($function_table{$name})) || 1079 ($output_selection == OUTPUT_INTERNAL !! 2080 (($output_selection == OUTPUT_EXCLUDE || 1080 !($functype eq "function" && defined !! 2081 $output_selection == OUTPUT_INTERNAL) && >> 2082 !($functype eq "function" && defined($function_table{$name})))) 1081 { 2083 { 1082 &$func(@_); !! 2084 &$func(@_); 1083 $section_counter++; !! 2085 $section_counter++; 1084 } 2086 } 1085 } 2087 } 1086 2088 1087 ## 2089 ## 1088 # generic output function - calls the right o 2090 # generic output function - calls the right one based on current output mode. 1089 sub output_blockhead { 2091 sub output_blockhead { 1090 no strict 'refs'; 2092 no strict 'refs'; 1091 my $func = "output_blockhead_" . $output_ 2093 my $func = "output_blockhead_" . $output_mode; 1092 &$func(@_); 2094 &$func(@_); 1093 $section_counter++; 2095 $section_counter++; 1094 } 2096 } 1095 2097 1096 ## 2098 ## 1097 # takes a declaration (struct, union, enum, t 2099 # takes a declaration (struct, union, enum, typedef) and 1098 # invokes the right handler. NOT called for f 2100 # invokes the right handler. NOT called for functions. 1099 sub dump_declaration($$) { 2101 sub dump_declaration($$) { 1100 no strict 'refs'; 2102 no strict 'refs'; 1101 my ($prototype, $file) = @_; 2103 my ($prototype, $file) = @_; 1102 my $func = "dump_" . $decl_type; 2104 my $func = "dump_" . $decl_type; 1103 &$func(@_); 2105 &$func(@_); 1104 } 2106 } 1105 2107 1106 sub dump_union($$) { 2108 sub dump_union($$) { 1107 dump_struct(@_); 2109 dump_struct(@_); 1108 } 2110 } 1109 2111 1110 sub dump_struct($$) { 2112 sub dump_struct($$) { 1111 my $x = shift; 2113 my $x = shift; 1112 my $file = shift; 2114 my $file = shift; 1113 my $decl_type; !! 2115 my $nested; 1114 my $members; << 1115 my $type = qr{struct|union}; << 1116 # For capturing struct/union definition b << 1117 my $qualifiers = qr{$attribute|__packed|_ << 1118 my $definition_body = qr{\{(.*)\}\s*$qual << 1119 my $struct_members = qr{($type)([^\{\};]+ << 1120 2116 1121 if ($x =~ /($type)\s+(\w+)\s*$definition_ !! 2117 if ($x =~ /(struct|union)\s+(\w+)\s*{(.*)}/) { 1122 $decl_type = $1; !! 2118 #my $decl_type = $1; 1123 $declaration_name = $2; !! 2119 $declaration_name = $2; 1124 $members = $3; !! 2120 my $members = $3; 1125 } elsif ($x =~ /typedef\s+($type)\s*$defi !! 2121 1126 $decl_type = $1; !! 2122 # ignore embedded structs or unions 1127 $declaration_name = $3; !! 2123 $members =~ s/({.*})//g; 1128 $members = $2; !! 2124 $nested = $1; 1129 } !! 2125 1130 !! 2126 # ignore members marked private: 1131 if ($members) { !! 2127 $members =~ s/\/\*\s*private:.*?\/\*\s*public:.*?\*\///gosi; 1132 if ($identifier ne $declaration_name) !! 2128 $members =~ s/\/\*\s*private:.*//gosi; 1133 emit_warning("${file}:$.", "expec !! 2129 # strip comments: 1134 return; !! 2130 $members =~ s/\/\*.*?\*\///gos; 1135 } !! 2131 $nested =~ s/\/\*.*?\*\///gos; 1136 !! 2132 # strip kmemcheck_bitfield_{begin,end}.*; 1137 # ignore members marked private: !! 2133 $members =~ s/kmemcheck_bitfield_.*?;//gos; 1138 $members =~ s/\/\*\s*private:.*?\/\*\ !! 2134 # strip attributes 1139 $members =~ s/\/\*\s*private:.*//gosi !! 2135 $members =~ s/__attribute__\s*\(\([a-z,_\*\s\(\)]*\)\)//i; 1140 # strip comments: !! 2136 $members =~ s/__aligned\s*\([^;]*\)//gos; 1141 $members =~ s/\/\*.*?\*\///gos; !! 2137 $members =~ s/\s*CRYPTO_MINALIGN_ATTR//gos; 1142 # strip attributes !! 2138 # replace DECLARE_BITMAP 1143 $members =~ s/\s*$attribute/ /gi; !! 2139 $members =~ s/DECLARE_BITMAP\s*\(([^,)]+), ([^,)]+)\)/unsigned long $1\[BITS_TO_LONGS($2)\]/gos; 1144 $members =~ s/\s*__aligned\s*\([^;]*\ !! 2140 1145 $members =~ s/\s*__counted_by\s*\([^; !! 2141 create_parameterlist($members, ';', $file); 1146 $members =~ s/\s*__counted_by_(le|be) !! 2142 check_sections($file, $declaration_name, "struct", $sectcheck, $struct_actual, $nested); 1147 $members =~ s/\s*__packed\s*/ /gos; !! 2143 1148 $members =~ s/\s*CRYPTO_MINALIGN_ATTR !! 2144 output_declaration($declaration_name, 1149 $members =~ s/\s*____cacheline_aligne !! 2145 'struct', 1150 $members =~ s/\s*____cacheline_aligne !! 2146 {'struct' => $declaration_name, 1151 # unwrap struct_group(): !! 2147 'module' => $modulename, 1152 # - first eat non-declaration paramet !! 2148 'parameterlist' => \@parameterlist, 1153 # - then remove macro, outer parens, !! 2149 'parameterdescs' => \%parameterdescs, 1154 $members =~ s/\bstruct_group\s*\(([^, !! 2150 'parametertypes' => \%parametertypes, 1155 $members =~ s/\bstruct_group_attr\s*\ !! 2151 'sectionlist' => \@sectionlist, 1156 $members =~ s/\bstruct_group_tagged\s !! 2152 'sections' => \%sections, 1157 $members =~ s/\b__struct_group\s*\(([ !! 2153 'purpose' => $declaration_purpose, 1158 $members =~ s/\bSTRUCT_GROUP(\(((?:(? !! 2154 'type' => $decl_type 1159 !! 2155 }); 1160 my $args = qr{([^,)]+)}; !! 2156 } 1161 # replace DECLARE_BITMAP !! 2157 else { 1162 $members =~ s/__ETHTOOL_DECLARE_LINK_ !! 2158 print STDERR "${file}:$.: error: Cannot parse struct or union!\n"; 1163 $members =~ s/DECLARE_PHY_INTERFACE_M !! 2159 ++$errors; 1164 $members =~ s/DECLARE_BITMAP\s*\($arg << 1165 # replace DECLARE_HASHTABLE << 1166 $members =~ s/DECLARE_HASHTABLE\s*\($ << 1167 # replace DECLARE_KFIFO << 1168 $members =~ s/DECLARE_KFIFO\s*\($args << 1169 # replace DECLARE_KFIFO_PTR << 1170 $members =~ s/DECLARE_KFIFO_PTR\s*\($ << 1171 # replace DECLARE_FLEX_ARRAY << 1172 $members =~ s/(?:__)?DECLARE_FLEX_ARR << 1173 #replace DEFINE_DMA_UNMAP_ADDR << 1174 $members =~ s/DEFINE_DMA_UNMAP_ADDR\s << 1175 #replace DEFINE_DMA_UNMAP_LEN << 1176 $members =~ s/DEFINE_DMA_UNMAP_LEN\s* << 1177 my $declaration = $members; << 1178 << 1179 # Split nested struct/union elements << 1180 while ($members =~ m/$struct_members/ << 1181 my $newmember; << 1182 my $maintype = $1; << 1183 my $ids = $4; << 1184 my $content = $3; << 1185 foreach my $id(split /,/, $ids) { << 1186 $newmember .= "$maintype $id; << 1187 << 1188 $id =~ s/[:\[].*//; << 1189 $id =~ s/^\s*\**(\S+)\s*/$1/; << 1190 foreach my $arg (split /;/, $ << 1191 next if ($arg =~ m/^\s*$/ << 1192 if ($arg =~ m/^([^\(]+\(\ << 1193 # pointer-to-function << 1194 my $type = $1; << 1195 my $name = $2; << 1196 my $extra = $3; << 1197 next if (!$name); << 1198 if ($id =~ m/^\s*$/) << 1199 # anonymous struc << 1200 $newmember .= "$t << 1201 } else { << 1202 $newmember .= "$t << 1203 } << 1204 } else { << 1205 my $type; << 1206 my $names; << 1207 $arg =~ s/^\s+//; << 1208 $arg =~ s/\s+$//; << 1209 # Handle bitmaps << 1210 $arg =~ s/:\s*\d+\s*/ << 1211 # Handle arrays << 1212 $arg =~ s/\[.*\]//g; << 1213 # The type may have m << 1214 # and multiple IDs ca << 1215 # const struct foo << 1216 # So, we remove space << 1217 # names, in order to << 1218 # and commas for the << 1219 $arg =~ s/\s*,\s*/,/g << 1220 if ($arg =~ m/(.*)\s+ << 1221 $type = $1; << 1222 $names = $2; << 1223 } else { << 1224 $newmember .= "$a << 1225 next; << 1226 } << 1227 foreach my $name (spl << 1228 $name =~ s/^\s*\* << 1229 next if (($name = << 1230 if ($id =~ m/^\s* << 1231 # anonymous s << 1232 $newmember .= << 1233 } else { << 1234 $newmember .= << 1235 } << 1236 } << 1237 } << 1238 } << 1239 } << 1240 $members =~ s/$struct_members/$ne << 1241 } << 1242 << 1243 # Ignore other nested elements, like << 1244 $members =~ s/(\{[^\{\}]*\})//g; << 1245 << 1246 create_parameterlist($members, ';', $ << 1247 check_sections($file, $declaration_na << 1248 << 1249 # Adjust declaration for better displ << 1250 $declaration =~ s/([\{;])/$1\n/g; << 1251 $declaration =~ s/\}\s+;/};/g; << 1252 # Better handle inlined enums << 1253 do {} while ($declaration =~ s/(enum\ << 1254 << 1255 my @def_args = split /\n/, $declarati << 1256 my $level = 1; << 1257 $declaration = ""; << 1258 foreach my $clause (@def_args) { << 1259 $clause =~ s/^\s+//; << 1260 $clause =~ s/\s+$//; << 1261 $clause =~ s/\s+/ /; << 1262 next if (!$clause); << 1263 $level-- if ($clause =~ m/(\})/ & << 1264 if (!($clause =~ m/^\s*#/)) { << 1265 $declaration .= "\t" x $level << 1266 } << 1267 $declaration .= "\t" . $clause . << 1268 $level++ if ($clause =~ m/(\{)/ & << 1269 } << 1270 output_declaration($declaration_name, << 1271 'struct', << 1272 {'struct' => $declaration_ << 1273 'module' => $modulename, << 1274 'definition' => $declarat << 1275 'parameterlist' => \@para << 1276 'parameterdescs' => \%par << 1277 'parametertypes' => \%par << 1278 'sectionlist' => \@sectio << 1279 'sections' => \%sections, << 1280 'purpose' => $declaration << 1281 'type' => $decl_type << 1282 }); << 1283 } else { << 1284 print STDERR "${file}:$.: error: Cann << 1285 ++$errors; << 1286 } << 1287 } << 1288 << 1289 << 1290 sub show_warnings($$) { << 1291 my $functype = shift; << 1292 my $name = shift; << 1293 << 1294 return 0 if (defined($nosymbol_table{$nam << 1295 << 1296 return 1 if ($output_selection == OUTPUT_ << 1297 << 1298 if ($output_selection == OUTPUT_EXPORTED) << 1299 if (defined($function_table{$name})) << 1300 return 1; << 1301 } else { << 1302 return 0; << 1303 } << 1304 } << 1305 if ($output_selection == OUTPUT_INTERNAL) << 1306 if (!($functype eq "function" && defi << 1307 return 1; << 1308 } else { << 1309 return 0; << 1310 } << 1311 } << 1312 if ($output_selection == OUTPUT_INCLUDE) << 1313 if (defined($function_table{$name})) << 1314 return 1; << 1315 } else { << 1316 return 0; << 1317 } << 1318 } 2160 } 1319 die("Please add the new output type at sh << 1320 } 2161 } 1321 2162 1322 sub dump_enum($$) { 2163 sub dump_enum($$) { 1323 my $x = shift; 2164 my $x = shift; 1324 my $file = shift; 2165 my $file = shift; 1325 my $members; << 1326 << 1327 # ignore members marked private: << 1328 $x =~ s/\/\*\s*private:.*?\/\*\s*public:. << 1329 $x =~ s/\/\*\s*private:.*}/}/gosi; << 1330 2166 1331 $x =~ s@/\*.*?\*/@@gos; # strip comme 2167 $x =~ s@/\*.*?\*/@@gos; # strip comments. 1332 # strip #define macros inside enums 2168 # strip #define macros inside enums 1333 $x =~ s@#\s*((define|ifdef|if)\s+|endif)[ !! 2169 $x =~ s@#\s*((define|ifdef)\s+|endif)[^;]*;@@gos; 1334 2170 1335 if ($x =~ /typedef\s+enum\s*\{(.*)\}\s*(\ !! 2171 if ($x =~ /enum\s+(\w+)\s*{(.*)}/) { 1336 $declaration_name = $2; !! 2172 $declaration_name = $1; 1337 $members = $1; !! 2173 my $members = $2; 1338 } elsif ($x =~ /enum\s+(\w*)\s*\{(.*)\}/) !! 2174 1339 $declaration_name = $1; !! 2175 foreach my $arg (split ',', $members) { 1340 $members = $2; !! 2176 $arg =~ s/^\s*(\w+).*/$1/; 1341 } !! 2177 push @parameterlist, $arg; 1342 !! 2178 if (!$parameterdescs{$arg}) { 1343 if ($members) { !! 2179 $parameterdescs{$arg} = $undescribed; 1344 if ($identifier ne $declaration_name) !! 2180 print STDERR "${file}:$.: warning: Enum value '$arg' ". 1345 if ($identifier eq "") { !! 2181 "not described in enum '$declaration_name'\n"; 1346 emit_warning("${file}:$.", "w !! 2182 } 1347 } else { !! 2183 1348 emit_warning("${file}:$.", "e !! 2184 } 1349 } !! 2185 1350 return; !! 2186 output_declaration($declaration_name, 1351 } !! 2187 'enum', 1352 $declaration_name = "(anonymous)" if !! 2188 {'enum' => $declaration_name, 1353 !! 2189 'module' => $modulename, 1354 my %_members; !! 2190 'parameterlist' => \@parameterlist, 1355 !! 2191 'parameterdescs' => \%parameterdescs, 1356 $members =~ s/\s+$//; !! 2192 'sectionlist' => \@sectionlist, 1357 $members =~ s/\([^;]*?[\)]//g; !! 2193 'sections' => \%sections, 1358 !! 2194 'purpose' => $declaration_purpose 1359 foreach my $arg (split ',', $members) !! 2195 }); 1360 $arg =~ s/^\s*(\w+).*/$1/; !! 2196 } 1361 push @parameterlist, $arg; !! 2197 else { 1362 if (!$parameterdescs{$arg}) { !! 2198 print STDERR "${file}:$.: error: Cannot parse enum!\n"; 1363 $parameterdescs{$arg} = $unde !! 2199 ++$errors; 1364 if (show_warnings("enum", $de << 1365 emit_warning("${file}:$." << 1366 } << 1367 } << 1368 $_members{$arg} = 1; << 1369 } << 1370 << 1371 while (my ($k, $v) = each %parameterd << 1372 if (!exists($_members{$k})) { << 1373 if (show_warnings("enum", $de << 1374 emit_warning("${file}:$." << 1375 } << 1376 } << 1377 } << 1378 << 1379 output_declaration($declaration_name, << 1380 'enum', << 1381 {'enum' => $declar << 1382 'module' => $modu << 1383 'parameterlist' = << 1384 'parameterdescs' << 1385 'sectionlist' => << 1386 'sections' => \%s << 1387 'purpose' => $dec << 1388 }); << 1389 } else { << 1390 print STDERR "${file}:$.: error: Cann << 1391 ++$errors; << 1392 } 2200 } 1393 } 2201 } 1394 2202 1395 my $typedef_type = qr { ((?:\s+[\w\*]+\b){1,8 << 1396 my $typedef_ident = qr { \*?\s*(\w\S+)\s* }x; << 1397 my $typedef_args = qr { \s*\((.*)\); }x; << 1398 << 1399 my $typedef1 = qr { typedef$typedef_type\($ty << 1400 my $typedef2 = qr { typedef$typedef_type$type << 1401 << 1402 sub dump_typedef($$) { 2203 sub dump_typedef($$) { 1403 my $x = shift; 2204 my $x = shift; 1404 my $file = shift; 2205 my $file = shift; 1405 2206 1406 $x =~ s@/\*.*?\*/@@gos; # strip comme 2207 $x =~ s@/\*.*?\*/@@gos; # strip comments. 1407 2208 1408 # Parse function typedef prototypes !! 2209 # Parse function prototypes 1409 if ($x =~ $typedef1 || $x =~ $typedef2) { !! 2210 if ($x =~ /typedef\s+(\w+)\s*\(\*\s*(\w\S+)\s*\)\s*\((.*)\);/ || 1410 $return_type = $1; !! 2211 $x =~ /typedef\s+(\w+)\s*(\w\S+)\s*\s*\((.*)\);/) { 1411 $declaration_name = $2; !! 2212 1412 my $args = $3; !! 2213 # Function typedefs 1413 $return_type =~ s/^\s+//; !! 2214 $return_type = $1; 1414 !! 2215 $declaration_name = $2; 1415 if ($identifier ne $declaration_name) !! 2216 my $args = $3; 1416 emit_warning("${file}:$.", "expec !! 2217 1417 return; !! 2218 create_parameterlist($args, ',', $file); 1418 } !! 2219 1419 !! 2220 output_declaration($declaration_name, 1420 create_parameterlist($args, ',', $fil !! 2221 'function', 1421 !! 2222 {'function' => $declaration_name, 1422 output_declaration($declaration_name, !! 2223 'typedef' => 1, 1423 'function', !! 2224 'module' => $modulename, 1424 {'function' => $de !! 2225 'functiontype' => $return_type, 1425 'typedef' => 1, !! 2226 'parameterlist' => \@parameterlist, 1426 'module' => $modu !! 2227 'parameterdescs' => \%parameterdescs, 1427 'functiontype' => !! 2228 'parametertypes' => \%parametertypes, 1428 'parameterlist' = !! 2229 'sectionlist' => \@sectionlist, 1429 'parameterdescs' !! 2230 'sections' => \%sections, 1430 'parametertypes' !! 2231 'purpose' => $declaration_purpose 1431 'sectionlist' => !! 2232 }); 1432 'sections' => \%s !! 2233 return; 1433 'purpose' => $dec << 1434 }); << 1435 return; << 1436 } 2234 } 1437 2235 1438 while (($x =~ /\(*.\)\s*;$/) || ($x =~ /\ 2236 while (($x =~ /\(*.\)\s*;$/) || ($x =~ /\[*.\]\s*;$/)) { 1439 $x =~ s/\(*.\)\s*;$/;/; !! 2237 $x =~ s/\(*.\)\s*;$/;/; 1440 $x =~ s/\[*.\]\s*;$/;/; !! 2238 $x =~ s/\[*.\]\s*;$/;/; 1441 } 2239 } 1442 2240 1443 if ($x =~ /typedef.*\s+(\w+)\s*;/) { 2241 if ($x =~ /typedef.*\s+(\w+)\s*;/) { 1444 $declaration_name = $1; !! 2242 $declaration_name = $1; 1445 << 1446 if ($identifier ne $declaration_name) << 1447 emit_warning("${file}:$.", "expec << 1448 return; << 1449 } << 1450 2243 1451 output_declaration($declaration_name, !! 2244 output_declaration($declaration_name, 1452 'typedef', !! 2245 'typedef', 1453 {'typedef' => $dec !! 2246 {'typedef' => $declaration_name, 1454 'module' => $modu !! 2247 'module' => $modulename, 1455 'sectionlist' => !! 2248 'sectionlist' => \@sectionlist, 1456 'sections' => \%s !! 2249 'sections' => \%sections, 1457 'purpose' => $dec !! 2250 'purpose' => $declaration_purpose 1458 }); !! 2251 }); 1459 } else { !! 2252 } 1460 print STDERR "${file}:$.: error: Cann !! 2253 else { 1461 ++$errors; !! 2254 print STDERR "${file}:$.: error: Cannot parse typedef!\n"; >> 2255 ++$errors; 1462 } 2256 } 1463 } 2257 } 1464 2258 1465 sub save_struct_actual($) { 2259 sub save_struct_actual($) { 1466 my $actual = shift; 2260 my $actual = shift; 1467 2261 1468 # strip all spaces from the actual param 2262 # strip all spaces from the actual param so that it looks like one string item 1469 $actual =~ s/\s*//g; 2263 $actual =~ s/\s*//g; 1470 $struct_actual = $struct_actual . $actual 2264 $struct_actual = $struct_actual . $actual . " "; 1471 } 2265 } 1472 2266 1473 sub create_parameterlist($$$$) { !! 2267 sub create_parameterlist($$$) { 1474 my $args = shift; 2268 my $args = shift; 1475 my $splitter = shift; 2269 my $splitter = shift; 1476 my $file = shift; 2270 my $file = shift; 1477 my $declaration_name = shift; << 1478 my $type; 2271 my $type; 1479 my $param; 2272 my $param; 1480 2273 1481 # temporarily replace commas inside funct 2274 # temporarily replace commas inside function pointer definition 1482 my $arg_expr = qr{\([^\),]+}; !! 2275 while ($args =~ /(\([^\),]+),/) { 1483 while ($args =~ /$arg_expr,/) { !! 2276 $args =~ s/(\([^\),]+),/$1#/g; 1484 $args =~ s/($arg_expr),/$1#/g; << 1485 } 2277 } 1486 2278 1487 foreach my $arg (split($splitter, $args)) 2279 foreach my $arg (split($splitter, $args)) { 1488 # strip comments !! 2280 # strip comments 1489 $arg =~ s/\/\*.*\*\///; !! 2281 $arg =~ s/\/\*.*\*\///; 1490 # ignore argument attributes !! 2282 # strip leading/trailing spaces 1491 $arg =~ s/\sPOS0?\s/ /; !! 2283 $arg =~ s/^\s*//; 1492 # strip leading/trailing spaces !! 2284 $arg =~ s/\s*$//; 1493 $arg =~ s/^\s*//; !! 2285 $arg =~ s/\s+/ /; 1494 $arg =~ s/\s*$//; !! 2286 1495 $arg =~ s/\s+/ /; !! 2287 if ($arg =~ /^#/) { 1496 !! 2288 # Treat preprocessor directive as a typeless variable just to fill 1497 if ($arg =~ /^#/) { !! 2289 # corresponding data structures "correctly". Catch it later in 1498 # Treat preprocessor directive as !! 2290 # output_* subs. 1499 # corresponding data structures " !! 2291 push_parameter($arg, "", $file); 1500 # output_* subs. !! 2292 } elsif ($arg =~ m/\(.+\)\s*\(/) { 1501 push_parameter($arg, "", "", $fil !! 2293 # pointer-to-function 1502 } elsif ($arg =~ m/\(.+\)\s*\(/) { !! 2294 $arg =~ tr/#/,/; 1503 # pointer-to-function !! 2295 $arg =~ m/[^\(]+\(\*?\s*(\w*)\s*\)/; 1504 $arg =~ tr/#/,/; !! 2296 $param = $1; 1505 $arg =~ m/[^\(]+\(\*?\s*([\w\[\]\ !! 2297 $type = $arg; 1506 $param = $1; !! 2298 $type =~ s/([^\(]+\(\*?)\s*$param/$1/; 1507 $type = $arg; !! 2299 save_struct_actual($param); 1508 $type =~ s/([^\(]+\(\*?)\s*$param !! 2300 push_parameter($param, $type, $file); 1509 save_struct_actual($param); !! 2301 } elsif ($arg) { 1510 push_parameter($param, $type, $ar !! 2302 $arg =~ s/\s*:\s*/:/g; 1511 } elsif ($arg =~ m/\(.+\)\s*\[/) { !! 2303 $arg =~ s/\s*\[/\[/g; 1512 # array-of-pointers !! 2304 1513 $arg =~ tr/#/,/; !! 2305 my @args = split('\s*,\s*', $arg); 1514 $arg =~ m/[^\(]+\(\s*\*\s*([\w\[\ !! 2306 if ($args[0] =~ m/\*/) { 1515 $param = $1; !! 2307 $args[0] =~ s/(\*+)\s*/ $1/; 1516 $type = $arg; !! 2308 } 1517 $type =~ s/([^\(]+\(\*?)\s*$param !! 2309 1518 save_struct_actual($param); !! 2310 my @first_arg; 1519 push_parameter($param, $type, $ar !! 2311 if ($args[0] =~ /^(.*\s+)(.*?\[.*\].*)$/) { 1520 } elsif ($arg) { !! 2312 shift @args; 1521 $arg =~ s/\s*:\s*/:/g; !! 2313 push(@first_arg, split('\s+', $1)); 1522 $arg =~ s/\s*\[/\[/g; !! 2314 push(@first_arg, $2); 1523 !! 2315 } else { 1524 my @args = split('\s*,\s*', $arg) !! 2316 @first_arg = split('\s+', shift @args); 1525 if ($args[0] =~ m/\*/) { !! 2317 } 1526 $args[0] =~ s/(\*+)\s*/ $1/; !! 2318 1527 } !! 2319 unshift(@args, pop @first_arg); 1528 !! 2320 $type = join " ", @first_arg; 1529 my @first_arg; !! 2321 1530 if ($args[0] =~ /^(.*\s+)(.*?\[.* !! 2322 foreach $param (@args) { 1531 shift @args; !! 2323 if ($param =~ m/^(\*+)\s*(.*)/) { 1532 push(@first_arg, split('\s+', !! 2324 save_struct_actual($2); 1533 push(@first_arg, $2); !! 2325 push_parameter($2, "$type $1", $file); 1534 } else { !! 2326 } 1535 @first_arg = split('\s+', shi !! 2327 elsif ($param =~ m/(.*?):(\d+)/) { 1536 } !! 2328 if ($type ne "") { # skip unnamed bit-fields 1537 !! 2329 save_struct_actual($1); 1538 unshift(@args, pop @first_arg); !! 2330 push_parameter($1, "$type:$2", $file) 1539 $type = join " ", @first_arg; !! 2331 } 1540 !! 2332 } 1541 foreach $param (@args) { !! 2333 else { 1542 if ($param =~ m/^(\*+)\s*(.*) !! 2334 save_struct_actual($param); 1543 save_struct_actual($2); !! 2335 push_parameter($param, $type, $file); 1544 !! 2336 } 1545 push_parameter($2, "$type !! 2337 } 1546 } elsif ($param =~ m/(.*?):(\ !! 2338 } 1547 if ($type ne "") { # skip !! 2339 } 1548 save_struct_actual($1 !! 2340 } 1549 push_parameter($1, "$ !! 2341 1550 } !! 2342 sub push_parameter($$$) { 1551 } else { !! 2343 my $param = shift; 1552 save_struct_actual($param !! 2344 my $type = shift; 1553 push_parameter($param, $t !! 2345 my $file = shift; 1554 } !! 2346 1555 } !! 2347 if (($anon_struct_union == 1) && ($type eq "") && 1556 } !! 2348 ($param eq "}")) { 1557 } !! 2349 return; # ignore the ending }; from anon. struct/union 1558 } !! 2350 } 1559 !! 2351 1560 sub push_parameter($$$$$) { !! 2352 $anon_struct_union = 0; 1561 my $param = shift; !! 2353 my $param_name = $param; 1562 my $type = shift; !! 2354 $param_name =~ s/\[.*//; 1563 my $org_arg = shift; !! 2355 1564 my $file = shift; !! 2356 if ($type eq "" && $param =~ /\.\.\.$/) 1565 my $declaration_name = shift; !! 2357 { 1566 !! 2358 if (!$param =~ /\w\.\.\.$/) { 1567 if (($anon_struct_union == 1) && ($type e !! 2359 # handles unnamed variable parameters 1568 ($param eq "}")) { !! 2360 $param = "..."; 1569 return; # ignore the ending }; !! 2361 } 1570 } !! 2362 if (!defined $parameterdescs{$param} || $parameterdescs{$param} eq "") { 1571 !! 2363 $parameterdescs{$param} = "variable arguments"; 1572 $anon_struct_union = 0; !! 2364 } 1573 $param =~ s/[\[\)].*//; !! 2365 } 1574 !! 2366 elsif ($type eq "" && ($param eq "" or $param eq "void")) 1575 if ($type eq "" && $param =~ /\.\.\.$/) !! 2367 { 1576 { !! 2368 $param="void"; 1577 if (!$param =~ /\w\.\.\.$/) { !! 2369 $parameterdescs{void} = "no arguments"; 1578 # handles unnamed variable parame !! 2370 } 1579 $param = "..."; !! 2371 elsif ($type eq "" && ($param eq "struct" or $param eq "union")) 1580 } elsif ($param =~ /\w\.\.\.$/) { !! 2372 # handle unnamed (anonymous) union or struct: 1581 # for named variable parameters o !! 2373 { 1582 $param =~ s/\.\.\.$//; !! 2374 $type = $param; 1583 } !! 2375 $param = "{unnamed_" . $param . "}"; 1584 if (!defined $parameterdescs{$param} !! 2376 $parameterdescs{$param} = "anonymous\n"; 1585 $parameterdescs{$param} = "variab !! 2377 $anon_struct_union = 1; 1586 } !! 2378 } 1587 } !! 2379 1588 elsif ($type eq "" && ($param eq "" or $p !! 2380 # warn if parameter has no description 1589 { !! 2381 # (but ignore ones starting with # as these are not parameters 1590 $param="void"; !! 2382 # but inline preprocessor statements); 1591 $parameterdescs{void} = "no arguments !! 2383 # also ignore unnamed structs/unions; 1592 } !! 2384 if (!$anon_struct_union) { 1593 elsif ($type eq "" && ($param eq "struct" !! 2385 if (!defined $parameterdescs{$param_name} && $param_name !~ /^#/) { 1594 # handle unnamed (anonymous) union or str !! 2386 1595 { !! 2387 $parameterdescs{$param_name} = $undescribed; 1596 $type = $param; !! 2388 1597 $param = "{unnamed_" . $param . "}"; !! 2389 if (($type eq 'function') || ($type eq 'enum')) { 1598 $parameterdescs{$param} = "anonymous\ !! 2390 print STDERR "${file}:$.: warning: Function parameter ". 1599 $anon_struct_union = 1; !! 2391 "or member '$param' not " . 1600 } !! 2392 "described in '$declaration_name'\n"; 1601 elsif ($param =~ "__cacheline_group" ) !! 2393 } 1602 # handle cache group enforcing variables: !! 2394 print STDERR "${file}:$.: warning:" . 1603 { !! 2395 " No description found for parameter '$param'\n"; 1604 return; # ignore __cacheline_group_be !! 2396 ++$warnings; 1605 } !! 2397 } 1606 !! 2398 } 1607 # warn if parameter has no description !! 2399 1608 # (but ignore ones starting with # as the !! 2400 $param = xml_escape($param); 1609 # but inline preprocessor statements); !! 2401 1610 # Note: It will also ignore void params a !! 2402 # strip spaces from $param so that it is one continuous string 1611 if (!defined $parameterdescs{$param} && $ !! 2403 # on @parameterlist; 1612 $parameterdescs{$param} = $undescribe !! 2404 # this fixes a problem where check_sections() cannot find 1613 !! 2405 # a parameter like "addr[6 + 2]" because it actually appears 1614 if (show_warnings($type, $declaration !! 2406 # as "addr[6", "+", "2]" on the parameter list; 1615 emit_warning("${file}:$.", "Funct !! 2407 # but it's better to maintain the param string unchanged for output, 1616 } !! 2408 # so just weaken the string compare in check_sections() to ignore 1617 } !! 2409 # "[blah" in a parameter string; 1618 !! 2410 ###$param =~ s/\s*//g; 1619 # strip spaces from $param so that it is !! 2411 push @parameterlist, $param; 1620 # on @parameterlist; !! 2412 $parametertypes{$param} = $type; 1621 # this fixes a problem where check_sectio !! 2413 } 1622 # a parameter like "addr[6 + 2]" because !! 2414 1623 # as "addr[6", "+", "2]" on the parameter !! 2415 sub check_sections($$$$$$) { 1624 # but it's better to maintain the param s !! 2416 my ($file, $decl_name, $decl_type, $sectcheck, $prmscheck, $nested) = @_; 1625 # so just weaken the string compare in ch !! 2417 my @sects = split ' ', $sectcheck; 1626 # "[blah" in a parameter string; !! 2418 my @prms = split ' ', $prmscheck; 1627 ###$param =~ s/\s*//g; !! 2419 my $err; 1628 push @parameterlist, $param; !! 2420 my ($px, $sx); 1629 $org_arg =~ s/\s\s+/ /g; !! 2421 my $prm_clean; # strip trailing "[array size]" and/or beginning "*" 1630 $parametertypes{$param} = $org_arg; !! 2422 1631 } !! 2423 foreach $sx (0 .. $#sects) { 1632 !! 2424 $err = 1; 1633 sub check_sections($$$$$) { !! 2425 foreach $px (0 .. $#prms) { 1634 my ($file, $decl_name, $decl_type, $sectc !! 2426 $prm_clean = $prms[$px]; 1635 my @sects = split ' ', $sectcheck; !! 2427 $prm_clean =~ s/\[.*\]//; 1636 my @prms = split ' ', $prmscheck; !! 2428 $prm_clean =~ s/__attribute__\s*\(\([a-z,_\*\s\(\)]*\)\)//i; 1637 my $err; !! 2429 # ignore array size in a parameter string; 1638 my ($px, $sx); !! 2430 # however, the original param string may contain 1639 my $prm_clean; # strip trailing "[ !! 2431 # spaces, e.g.: addr[6 + 2] 1640 !! 2432 # and this appears in @prms as "addr[6" since the 1641 foreach $sx (0 .. $#sects) { !! 2433 # parameter list is split at spaces; 1642 $err = 1; !! 2434 # hence just ignore "[..." for the sections check; 1643 foreach $px (0 .. $#prms) { !! 2435 $prm_clean =~ s/\[.*//; 1644 $prm_clean = $prms[$px]; !! 2436 1645 $prm_clean =~ s/\[.*\]//; !! 2437 ##$prm_clean =~ s/^\**//; 1646 $prm_clean =~ s/$attribute//i; !! 2438 if ($prm_clean eq $sects[$sx]) { 1647 # ignore array size in a paramete !! 2439 $err = 0; 1648 # however, the original param str !! 2440 last; 1649 # spaces, e.g.: addr[6 + 2] !! 2441 } 1650 # and this appears in @prms as "a !! 2442 } 1651 # parameter list is split at spac !! 2443 if ($err) { 1652 # hence just ignore "[..." for th !! 2444 if ($decl_type eq "function") { 1653 $prm_clean =~ s/\[.*//; !! 2445 print STDERR "${file}:$.: warning: " . 1654 !! 2446 "Excess function parameter " . 1655 ##$prm_clean =~ s/^\**//; !! 2447 "'$sects[$sx]' " . 1656 if ($prm_clean eq $sects[$sx]) { !! 2448 "description in '$decl_name'\n"; 1657 $err = 0; !! 2449 ++$warnings; 1658 last; !! 2450 } else { 1659 } !! 2451 if ($nested !~ m/\Q$sects[$sx]\E/) { 1660 } !! 2452 print STDERR "${file}:$.: warning: " . 1661 if ($err) { !! 2453 "Excess struct/union/enum/typedef member " . 1662 if ($decl_type eq "function") { !! 2454 "'$sects[$sx]' " . 1663 emit_warning("${file}:$.", !! 2455 "description in '$decl_name'\n"; 1664 "Excess function paramete !! 2456 ++$warnings; 1665 "'$sects[$sx]' " . !! 2457 } 1666 "description in '$decl_na !! 2458 } 1667 } elsif (($decl_type eq "struct") !! 2459 } 1668 ($decl_type eq "uni !! 2460 } 1669 emit_warning("${file}:$.", << 1670 "Excess $decl_type member << 1671 "'$sects[$sx]' " . << 1672 "description in '$decl_na << 1673 } << 1674 } << 1675 } << 1676 } 2461 } 1677 2462 1678 ## 2463 ## 1679 # Checks the section describing the return va 2464 # Checks the section describing the return value of a function. 1680 sub check_return_section { 2465 sub check_return_section { 1681 my $file = shift; !! 2466 my $file = shift; 1682 my $declaration_name = shift; !! 2467 my $declaration_name = shift; 1683 my $return_type = shift; !! 2468 my $return_type = shift; 1684 !! 2469 1685 # Ignore an empty return type (It's a mac !! 2470 # Ignore an empty return type (It's a macro) 1686 # Ignore functions with a "void" return t !! 2471 # Ignore functions with a "void" return type. (But don't ignore "void *") 1687 if (($return_type eq "") || ($return_type !! 2472 if (($return_type eq "") || ($return_type =~ /void\s*\w*\s*$/)) { 1688 return; !! 2473 return; 1689 } !! 2474 } 1690 !! 2475 1691 if (!defined($sections{$section_return}) !! 2476 if (!defined($sections{$section_return}) || 1692 $sections{$section_return} eq "") !! 2477 $sections{$section_return} eq "") { 1693 { !! 2478 print STDERR "${file}:$.: warning: " . 1694 emit_warning("${file}:$.", !! 2479 "No description found for return value of " . 1695 "No description found fo !! 2480 "'$declaration_name'\n"; 1696 "'$declaration_name'\n") !! 2481 ++$warnings; 1697 } !! 2482 } 1698 } 2483 } 1699 2484 1700 ## 2485 ## 1701 # takes a function prototype and the name of 2486 # takes a function prototype and the name of the current file being 1702 # processed and spits out all the details sto 2487 # processed and spits out all the details stored in the global 1703 # arrays/hashes. 2488 # arrays/hashes. 1704 sub dump_function($$) { 2489 sub dump_function($$) { 1705 my $prototype = shift; 2490 my $prototype = shift; 1706 my $file = shift; 2491 my $file = shift; 1707 my $noret = 0; 2492 my $noret = 0; 1708 2493 1709 print_lineno($new_start_line); << 1710 << 1711 $prototype =~ s/^static +//; 2494 $prototype =~ s/^static +//; 1712 $prototype =~ s/^extern +//; 2495 $prototype =~ s/^extern +//; 1713 $prototype =~ s/^asmlinkage +//; 2496 $prototype =~ s/^asmlinkage +//; 1714 $prototype =~ s/^inline +//; 2497 $prototype =~ s/^inline +//; 1715 $prototype =~ s/^__inline__ +//; 2498 $prototype =~ s/^__inline__ +//; 1716 $prototype =~ s/^__inline +//; 2499 $prototype =~ s/^__inline +//; 1717 $prototype =~ s/^__always_inline +//; 2500 $prototype =~ s/^__always_inline +//; 1718 $prototype =~ s/^noinline +//; 2501 $prototype =~ s/^noinline +//; 1719 $prototype =~ s/^__FORTIFY_INLINE +//; << 1720 $prototype =~ s/__init +//; 2502 $prototype =~ s/__init +//; 1721 $prototype =~ s/__init_or_module +//; 2503 $prototype =~ s/__init_or_module +//; 1722 $prototype =~ s/__deprecated +//; << 1723 $prototype =~ s/__flatten +//; << 1724 $prototype =~ s/__meminit +//; 2504 $prototype =~ s/__meminit +//; 1725 $prototype =~ s/__must_check +//; 2505 $prototype =~ s/__must_check +//; 1726 $prototype =~ s/__weak +//; 2506 $prototype =~ s/__weak +//; 1727 $prototype =~ s/__sched +//; << 1728 $prototype =~ s/_noprof//; << 1729 $prototype =~ s/__printf\s*\(\s*\d*\s*,\s << 1730 $prototype =~ s/__(?:re)?alloc_size\s*\(\ << 1731 $prototype =~ s/__diagnose_as\s*\(\s*\S+\ << 1732 $prototype =~ s/DECL_BUCKET_PARAMS\s*\(\s << 1733 my $define = $prototype =~ s/^#\s*define\ 2507 my $define = $prototype =~ s/^#\s*define\s+//; #ak added 1734 $prototype =~ s/__attribute_const__ +//; !! 2508 $prototype =~ s/__attribute__\s*\(\([a-z,]*\)\)//; 1735 $prototype =~ s/__attribute__\s*\(\( << 1736 (?: << 1737 [\w\s]++ # attribut << 1738 (?:\([^)]*+\))? # attribut << 1739 \s*+,? # optional << 1740 )+ << 1741 \)\)\s+//x; << 1742 2509 1743 # Yes, this truly is vile. We are lookin 2510 # Yes, this truly is vile. We are looking for: 1744 # 1. Return type (may be nothing if we're 2511 # 1. Return type (may be nothing if we're looking at a macro) 1745 # 2. Function name 2512 # 2. Function name 1746 # 3. Function parameters. 2513 # 3. Function parameters. 1747 # 2514 # 1748 # All the while we have to watch out for 2515 # All the while we have to watch out for function pointer parameters 1749 # (which IIRC is what the two sections ar 2516 # (which IIRC is what the two sections are for), C types (these 1750 # regexps don't even start to express all 2517 # regexps don't even start to express all the possibilities), and 1751 # so on. 2518 # so on. 1752 # 2519 # 1753 # If you mess with these regexps, it's a 2520 # If you mess with these regexps, it's a good idea to check that 1754 # the following functions' documentation 2521 # the following functions' documentation still comes out right: 1755 # - parport_register_device (function poi 2522 # - parport_register_device (function pointer parameters) 1756 # - atomic_set (macro) 2523 # - atomic_set (macro) 1757 # - pci_match_device, __copy_to_user (lon 2524 # - pci_match_device, __copy_to_user (long return type) 1758 my $name = qr{[a-zA-Z0-9_~:]+}; << 1759 my $prototype_end1 = qr{[^\(]*}; << 1760 my $prototype_end2 = qr{[^\{]*}; << 1761 my $prototype_end = qr{\(($prototype_end1 << 1762 my $type1 = qr{[\w\s]+}; << 1763 my $type2 = qr{$type1\*+}; << 1764 2525 1765 if ($define && $prototype =~ m/^()($name) !! 2526 if ($define && $prototype =~ m/^()([a-zA-Z0-9_~:]+)\s+/) { 1766 # This is an object-like macro, it ha 2527 # This is an object-like macro, it has no return type and no parameter 1767 # list. 2528 # list. 1768 # Function-like macros are not allowe 2529 # Function-like macros are not allowed to have spaces between 1769 # declaration_name and opening parent 2530 # declaration_name and opening parenthesis (notice the \s+). 1770 $return_type = $1; 2531 $return_type = $1; 1771 $declaration_name = $2; 2532 $declaration_name = $2; 1772 $noret = 1; 2533 $noret = 1; 1773 } elsif ($prototype =~ m/^()($name)\s*$pr !! 2534 } elsif ($prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || 1774 $prototype =~ m/^($type1)\s+($name)\s !! 2535 $prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || 1775 $prototype =~ m/^($type2+)\s*($name)\ !! 2536 $prototype =~ m/^(\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || 1776 $return_type = $1; !! 2537 $prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || 1777 $declaration_name = $2; !! 2538 $prototype =~ m/^(\w+\s+\w+\s*\*+)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || 1778 my $args = $3; !! 2539 $prototype =~ m/^(\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || >> 2540 $prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || >> 2541 $prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || >> 2542 $prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || >> 2543 $prototype =~ m/^(\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || >> 2544 $prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || >> 2545 $prototype =~ m/^(\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || >> 2546 $prototype =~ m/^(\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || >> 2547 $prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || >> 2548 $prototype =~ m/^(\w+\s+\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || >> 2549 $prototype =~ m/^(\w+\s+\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || >> 2550 $prototype =~ m/^(\w+\s+\w+\s*\*\s*\w+\s*\*\s*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/) { >> 2551 $return_type = $1; >> 2552 $declaration_name = $2; >> 2553 my $args = $3; 1779 2554 1780 create_parameterlist($args, ',', $fil !! 2555 create_parameterlist($args, ',', $file); 1781 } else { 2556 } else { 1782 emit_warning("${file}:$.", "cannot un !! 2557 print STDERR "${file}:$.: warning: cannot understand function prototype: '$prototype'\n"; 1783 return; !! 2558 return; 1784 } 2559 } 1785 2560 1786 if ($identifier ne $declaration_name) { !! 2561 my $prms = join " ", @parameterlist; 1787 emit_warning("${file}:$.", "expecting !! 2562 check_sections($file, $declaration_name, "function", $sectcheck, $prms, ""); 1788 return; << 1789 } << 1790 << 1791 my $prms = join " ", @parameterlist; << 1792 check_sections($file, $declaration_name, << 1793 2563 1794 # This check emits a lot of warnings at t !! 2564 # This check emits a lot of warnings at the moment, because many 1795 # functions don't have a 'Return' doc sec !! 2565 # functions don't have a 'Return' doc section. So until the number 1796 # of warnings goes sufficiently down, the !! 2566 # of warnings goes sufficiently down, the check is only performed in 1797 # -Wreturn mode. !! 2567 # verbose mode. 1798 # TODO: always perform the check. !! 2568 # TODO: always perform the check. 1799 if ($Wreturn && !$noret) { !! 2569 if ($verbose && !$noret) { 1800 check_return_section($file, $declarat !! 2570 check_return_section($file, $declaration_name, $return_type); 1801 } !! 2571 } 1802 !! 2572 1803 # The function parser can be called with !! 2573 output_declaration($declaration_name, 1804 # Handle it. !! 2574 'function', 1805 if ($return_type =~ /typedef/) { !! 2575 {'function' => $declaration_name, 1806 output_declaration($declaration_name, !! 2576 'module' => $modulename, 1807 'function', !! 2577 'functiontype' => $return_type, 1808 {'function' => $de !! 2578 'parameterlist' => \@parameterlist, 1809 'typedef' => 1, !! 2579 'parameterdescs' => \%parameterdescs, 1810 'module' => $modu !! 2580 'parametertypes' => \%parametertypes, 1811 'functiontype' => !! 2581 'sectionlist' => \@sectionlist, 1812 'parameterlist' = !! 2582 'sections' => \%sections, 1813 'parameterdescs' !! 2583 'purpose' => $declaration_purpose 1814 'parametertypes' !! 2584 }); 1815 'sectionlist' => << 1816 'sections' => \%s << 1817 'purpose' => $dec << 1818 }); << 1819 } else { << 1820 output_declaration($declaration_name, << 1821 'function', << 1822 {'function' => $de << 1823 'module' => $modu << 1824 'functiontype' => << 1825 'parameterlist' = << 1826 'parameterdescs' << 1827 'parametertypes' << 1828 'sectionlist' => << 1829 'sections' => \%s << 1830 'purpose' => $dec << 1831 }); << 1832 } << 1833 } 2585 } 1834 2586 1835 sub reset_state { 2587 sub reset_state { 1836 $function = ""; 2588 $function = ""; 1837 %parameterdescs = (); 2589 %parameterdescs = (); 1838 %parametertypes = (); 2590 %parametertypes = (); 1839 @parameterlist = (); 2591 @parameterlist = (); 1840 %sections = (); 2592 %sections = (); 1841 @sectionlist = (); 2593 @sectionlist = (); 1842 $sectcheck = ""; 2594 $sectcheck = ""; 1843 $struct_actual = ""; 2595 $struct_actual = ""; 1844 $prototype = ""; 2596 $prototype = ""; 1845 2597 1846 $state = STATE_NORMAL; 2598 $state = STATE_NORMAL; 1847 $inline_doc_state = STATE_INLINE_NA; 2599 $inline_doc_state = STATE_INLINE_NA; 1848 } 2600 } 1849 2601 1850 sub tracepoint_munge($) { 2602 sub tracepoint_munge($) { 1851 my $file = shift; !! 2603 my $file = shift; 1852 my $tracepointname = 0; !! 2604 my $tracepointname = 0; 1853 my $tracepointargs = 0; !! 2605 my $tracepointargs = 0; 1854 !! 2606 1855 if ($prototype =~ m/TRACE_EVENT\((.*?),/) !! 2607 if ($prototype =~ m/TRACE_EVENT\((.*?),/) { 1856 $tracepointname = $1; !! 2608 $tracepointname = $1; 1857 } !! 2609 } 1858 if ($prototype =~ m/DEFINE_SINGLE_EVENT\( !! 2610 if ($prototype =~ m/DEFINE_SINGLE_EVENT\((.*?),/) { 1859 $tracepointname = $1; !! 2611 $tracepointname = $1; 1860 } !! 2612 } 1861 if ($prototype =~ m/DEFINE_EVENT\((.*?),( !! 2613 if ($prototype =~ m/DEFINE_EVENT\((.*?),(.*?),/) { 1862 $tracepointname = $2; !! 2614 $tracepointname = $2; 1863 } !! 2615 } 1864 $tracepointname =~ s/^\s+//; #strip leadi !! 2616 $tracepointname =~ s/^\s+//; #strip leading whitespace 1865 if ($prototype =~ m/TP_PROTO\((.*?)\)/) { !! 2617 if ($prototype =~ m/TP_PROTO\((.*?)\)/) { 1866 $tracepointargs = $1; !! 2618 $tracepointargs = $1; 1867 } !! 2619 } 1868 if (($tracepointname eq 0) || ($tracepoin !! 2620 if (($tracepointname eq 0) || ($tracepointargs eq 0)) { 1869 emit_warning("${file}:$.", "Unrecogni !! 2621 print STDERR "${file}:$.: warning: Unrecognized tracepoint format: \n". 1870 "$prototype\n"); !! 2622 "$prototype\n"; 1871 } else { !! 2623 } else { 1872 $prototype = "static inline void trac !! 2624 $prototype = "static inline void trace_$tracepointname($tracepointargs)"; 1873 $identifier = "trace_$identifier"; !! 2625 } 1874 } << 1875 } 2626 } 1876 2627 1877 sub syscall_munge() { 2628 sub syscall_munge() { 1878 my $void = 0; !! 2629 my $void = 0; 1879 << 1880 $prototype =~ s@[\r\n]+@ @gos; # strip ne << 1881 ## if ($prototype =~ m/SYSCALL_DEFINE0\s*\ << 1882 if ($prototype =~ m/SYSCALL_DEFINE0/) { << 1883 $void = 1; << 1884 ## $prototype = "long sys_$1(void)"; << 1885 } << 1886 2630 1887 $prototype =~ s/SYSCALL_DEFINE.*\(/long s !! 2631 $prototype =~ s@[\r\n\t]+@ @gos; # strip newlines/CR's/tabs 1888 if ($prototype =~ m/long (sys_.*?),/) { !! 2632 ## if ($prototype =~ m/SYSCALL_DEFINE0\s*\(\s*(a-zA-Z0-9_)*\s*\)/) { 1889 $prototype =~ s/,/\(/; !! 2633 if ($prototype =~ m/SYSCALL_DEFINE0/) { 1890 } elsif ($void) { !! 2634 $void = 1; 1891 $prototype =~ s/\)/\(void\)/; !! 2635 ## $prototype = "long sys_$1(void)"; 1892 } !! 2636 } 1893 !! 2637 1894 # now delete all of the odd-number commas !! 2638 $prototype =~ s/SYSCALL_DEFINE.*\(/long sys_/; # fix return type & func name 1895 # so that arg types & arg names don't hav !! 2639 if ($prototype =~ m/long (sys_.*?),/) { 1896 my $count = 0; !! 2640 $prototype =~ s/,/\(/; 1897 my $len = length($prototype); !! 2641 } elsif ($void) { 1898 if ($void) { !! 2642 $prototype =~ s/\)/\(void\)/; 1899 $len = 0; # skip the for-loop !! 2643 } 1900 } !! 2644 1901 for (my $ix = 0; $ix < $len; $ix++) { !! 2645 # now delete all of the odd-number commas in $prototype 1902 if (substr($prototype, $ix, 1) eq ',' !! 2646 # so that arg types & arg names don't have a comma between them 1903 $count++; !! 2647 my $count = 0; 1904 if ($count % 2 == 1) { !! 2648 my $len = length($prototype); 1905 substr($prototype, $ix, 1) = !! 2649 if ($void) { 1906 } !! 2650 $len = 0; # skip the for-loop 1907 } !! 2651 } 1908 } !! 2652 for (my $ix = 0; $ix < $len; $ix++) { >> 2653 if (substr($prototype, $ix, 1) eq ',') { >> 2654 $count++; >> 2655 if ($count % 2 == 1) { >> 2656 substr($prototype, $ix, 1) = ' '; >> 2657 } >> 2658 } >> 2659 } 1909 } 2660 } 1910 2661 1911 sub process_proto_function($$) { 2662 sub process_proto_function($$) { 1912 my $x = shift; 2663 my $x = shift; 1913 my $file = shift; 2664 my $file = shift; 1914 2665 1915 $x =~ s@\/\/.*$@@gos; # strip C99-style c 2666 $x =~ s@\/\/.*$@@gos; # strip C99-style comments to end of line 1916 2667 1917 if ($x =~ /^#/ && $x !~ /^#\s*define/) { !! 2668 if ($x =~ m#\s*/\*\s+MACDOC\s*#io || ($x =~ /^#/ && $x !~ /^#\s*define/)) { 1918 # do nothing !! 2669 # do nothing 1919 } elsif ($x =~ /([^\{]*)/) { !! 2670 } 1920 $prototype .= $1; !! 2671 elsif ($x =~ /([^\{]*)/) { >> 2672 $prototype .= $1; 1921 } 2673 } 1922 2674 1923 if (($x =~ /\{/) || ($x =~ /\#\s*define/) 2675 if (($x =~ /\{/) || ($x =~ /\#\s*define/) || ($x =~ /;/)) { 1924 $prototype =~ s@/\*.*?\*/@@gos; !! 2676 $prototype =~ s@/\*.*?\*/@@gos; # strip comments. 1925 $prototype =~ s@[\r\n]+@ @gos; # stri !! 2677 $prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's. 1926 $prototype =~ s@^\s+@@gos; # strip le !! 2678 $prototype =~ s@^\s+@@gos; # strip leading spaces 1927 !! 2679 if ($prototype =~ /SYSCALL_DEFINE/) { 1928 # Handle prototypes for function poin !! 2680 syscall_munge(); 1929 # int (*pcs_config)(struct foo) !! 2681 } 1930 $prototype =~ s@^(\S+\s+)\(\s*\*(\S+) !! 2682 if ($prototype =~ /TRACE_EVENT/ || $prototype =~ /DEFINE_EVENT/ || 1931 !! 2683 $prototype =~ /DEFINE_SINGLE_EVENT/) 1932 if ($prototype =~ /SYSCALL_DEFINE/) { !! 2684 { 1933 syscall_munge(); !! 2685 tracepoint_munge($file); 1934 } !! 2686 } 1935 if ($prototype =~ /TRACE_EVENT/ || $p !! 2687 dump_function($prototype, $file); 1936 $prototype =~ /DEFINE_SINGLE_EVEN !! 2688 reset_state(); 1937 { << 1938 tracepoint_munge($file); << 1939 } << 1940 dump_function($prototype, $file); << 1941 reset_state(); << 1942 } 2689 } 1943 } 2690 } 1944 2691 1945 sub process_proto_type($$) { 2692 sub process_proto_type($$) { 1946 my $x = shift; 2693 my $x = shift; 1947 my $file = shift; 2694 my $file = shift; 1948 2695 1949 $x =~ s@[\r\n]+@ @gos; # strip newlines/c 2696 $x =~ s@[\r\n]+@ @gos; # strip newlines/cr's. 1950 $x =~ s@^\s+@@gos; # strip leading spaces 2697 $x =~ s@^\s+@@gos; # strip leading spaces 1951 $x =~ s@\s+$@@gos; # strip trailing space 2698 $x =~ s@\s+$@@gos; # strip trailing spaces 1952 $x =~ s@\/\/.*$@@gos; # strip C99-style c 2699 $x =~ s@\/\/.*$@@gos; # strip C99-style comments to end of line 1953 2700 1954 if ($x =~ /^#/) { 2701 if ($x =~ /^#/) { 1955 # To distinguish preprocessor directi !! 2702 # To distinguish preprocessor directive from regular declaration later. 1956 $x .= ";"; !! 2703 $x .= ";"; 1957 } 2704 } 1958 2705 1959 while (1) { 2706 while (1) { 1960 if ( $x =~ /([^\{\};]*)([\{\};])(.*)/ !! 2707 if ( $x =~ /([^{};]*)([{};])(.*)/ ) { 1961 if( length $prototype ) { !! 2708 $prototype .= $1 . $2; 1962 $prototype .= " " !! 2709 ($2 eq '{') && $brcount++; 1963 } !! 2710 ($2 eq '}') && $brcount--; 1964 $prototype .= $1 . $2; !! 2711 if (($2 eq ';') && ($brcount == 0)) { 1965 ($2 eq '{') && $brcount++; !! 2712 dump_declaration($prototype, $file); 1966 ($2 eq '}') && $brcount--; !! 2713 reset_state(); 1967 if (($2 eq ';') && ($brcount == 0 !! 2714 last; 1968 dump_declaration($prototype, !! 2715 } 1969 reset_state(); !! 2716 $x = $3; 1970 last; !! 2717 } else { 1971 } !! 2718 $prototype .= $x; 1972 $x = $3; !! 2719 last; 1973 } else { !! 2720 } 1974 $prototype .= $x; << 1975 last; << 1976 } << 1977 } 2721 } 1978 } 2722 } 1979 2723 >> 2724 # xml_escape: replace <, >, and & in the text stream; >> 2725 # >> 2726 # however, formatting controls that are generated internally/locally in the >> 2727 # kernel-doc script are not escaped here; instead, they begin life like >> 2728 # $blankline_html (4 of '\' followed by a mnemonic + ':'), then these strings >> 2729 # are converted to their mnemonic-expected output, without the 4 * '\' & ':', >> 2730 # just before actual output; (this is done by local_unescape()) >> 2731 sub xml_escape($) { >> 2732 my $text = shift; >> 2733 if (($output_mode eq "text") || ($output_mode eq "man")) { >> 2734 return $text; >> 2735 } >> 2736 $text =~ s/\&/\\\\\\amp;/g; >> 2737 $text =~ s/\</\\\\\\lt;/g; >> 2738 $text =~ s/\>/\\\\\\gt;/g; >> 2739 return $text; >> 2740 } >> 2741 >> 2742 # xml_unescape: reverse the effects of xml_escape >> 2743 sub xml_unescape($) { >> 2744 my $text = shift; >> 2745 if (($output_mode eq "text") || ($output_mode eq "man")) { >> 2746 return $text; >> 2747 } >> 2748 $text =~ s/\\\\\\amp;/\&/g; >> 2749 $text =~ s/\\\\\\lt;/</g; >> 2750 $text =~ s/\\\\\\gt;/>/g; >> 2751 return $text; >> 2752 } >> 2753 >> 2754 # convert local escape strings to html >> 2755 # local escape strings look like: '\\\\menmonic:' (that's 4 backslashes) >> 2756 sub local_unescape($) { >> 2757 my $text = shift; >> 2758 if (($output_mode eq "text") || ($output_mode eq "man")) { >> 2759 return $text; >> 2760 } >> 2761 $text =~ s/\\\\\\\\lt:/</g; >> 2762 $text =~ s/\\\\\\\\gt:/>/g; >> 2763 return $text; >> 2764 } 1980 2765 1981 sub map_filename($) { 2766 sub map_filename($) { 1982 my $file; 2767 my $file; 1983 my ($orig_file) = @_; 2768 my ($orig_file) = @_; 1984 2769 1985 if (defined($ENV{'SRCTREE'})) { 2770 if (defined($ENV{'SRCTREE'})) { 1986 $file = "$ENV{'SRCTREE'}" . "/" . $or !! 2771 $file = "$ENV{'SRCTREE'}" . "/" . $orig_file; 1987 } else { 2772 } else { 1988 $file = $orig_file; !! 2773 $file = $orig_file; 1989 } 2774 } 1990 2775 1991 if (defined($source_map{$file})) { 2776 if (defined($source_map{$file})) { 1992 $file = $source_map{$file}; !! 2777 $file = $source_map{$file}; 1993 } 2778 } 1994 2779 1995 return $file; 2780 return $file; 1996 } 2781 } 1997 2782 1998 sub process_export_file($) { 2783 sub process_export_file($) { 1999 my ($orig_file) = @_; 2784 my ($orig_file) = @_; 2000 my $file = map_filename($orig_file); 2785 my $file = map_filename($orig_file); 2001 2786 2002 if (!open(IN,"<$file")) { 2787 if (!open(IN,"<$file")) { 2003 print STDERR "Error: Cannot open file !! 2788 print STDERR "Error: Cannot open file $file\n"; 2004 ++$errors; !! 2789 ++$errors; 2005 return; !! 2790 return; 2006 } 2791 } 2007 2792 2008 while (<IN>) { 2793 while (<IN>) { 2009 if (/$export_symbol/) { !! 2794 if (/$export_symbol/) { 2010 next if (defined($nosymbol_table{ !! 2795 $function_table{$2} = 1; 2011 $function_table{$2} = 1; !! 2796 } 2012 } << 2013 if (/$export_symbol_ns/) { << 2014 next if (defined($nosymbol_table{ << 2015 $function_table{$2} = 1; << 2016 } << 2017 } 2797 } 2018 2798 2019 close(IN); 2799 close(IN); 2020 } 2800 } 2021 2801 2022 # << 2023 # Parsers for the various processing states. << 2024 # << 2025 # STATE_NORMAL: looking for the /** to begin << 2026 # << 2027 sub process_normal() { << 2028 if (/$doc_start/o) { << 2029 $state = STATE_NAME; # next li << 2030 $in_doc_sect = 0; << 2031 $declaration_start_line = $. + 1; << 2032 } << 2033 } << 2034 << 2035 # << 2036 # STATE_NAME: Looking for the "name - descrip << 2037 # << 2038 sub process_name($$) { << 2039 my $file = shift; << 2040 my $descr; << 2041 << 2042 if (/$doc_block/o) { << 2043 $state = STATE_DOCBLOCK; << 2044 $contents = ""; << 2045 $new_start_line = $.; << 2046 << 2047 if ( $1 eq "" ) { << 2048 $section = $section_intro; << 2049 } else { << 2050 $section = $1; << 2051 } << 2052 } elsif (/$doc_decl/o) { << 2053 $identifier = $1; << 2054 my $is_kernel_comment = 0; << 2055 my $decl_start = qr{$doc_com}; << 2056 # test for pointer declaration type, << 2057 my $fn_type = qr{\w+\s*\*\s*}; << 2058 my $parenthesis = qr{\(\w*\)}; << 2059 my $decl_end = qr{[-:].*}; << 2060 if (/^$decl_start([\w\s]+?)$parenthes << 2061 $identifier = $1; << 2062 } << 2063 if ($identifier =~ m/^(struct|union|e << 2064 $decl_type = $1; << 2065 $identifier = $2; << 2066 $is_kernel_comment = 1; << 2067 } << 2068 # Look for foo() or static void foo() << 2069 # identifier << 2070 elsif (/^$decl_start$fn_type?(\w+)\s* << 2071 /^$decl_start$fn_type?(\w+.*)$par << 2072 $identifier = $1; << 2073 $decl_type = 'function'; << 2074 $identifier =~ s/^define\s+//; << 2075 $is_kernel_comment = 1; << 2076 } << 2077 $identifier =~ s/\s+$//; << 2078 << 2079 $state = STATE_BODY; << 2080 # if there's no @param blocks need to << 2081 # here << 2082 $contents = ""; << 2083 $section = $section_default; << 2084 $new_start_line = $. + 1; << 2085 if (/[-:](.*)/) { << 2086 # strip leading/trailing/multiple << 2087 $descr= $1; << 2088 $descr =~ s/^\s*//; << 2089 $descr =~ s/\s*$//; << 2090 $descr =~ s/\s+/ /g; << 2091 $declaration_purpose = $descr; << 2092 $state = STATE_BODY_MAYBE; << 2093 } else { << 2094 $declaration_purpose = ""; << 2095 } << 2096 << 2097 if (!$is_kernel_comment) { << 2098 emit_warning("${file}:$.", "This << 2099 $state = STATE_NORMAL; << 2100 } << 2101 << 2102 if (($declaration_purpose eq "") && $ << 2103 emit_warning("${file}:$.", "missi << 2104 } << 2105 << 2106 if ($identifier eq "" && $decl_type n << 2107 emit_warning("${file}:$.", "wrong << 2108 $state = STATE_NORMAL; << 2109 } << 2110 << 2111 if ($verbose) { << 2112 print STDERR "${file}:$.: info: S << 2113 } << 2114 } else { << 2115 emit_warning("${file}:$.", "Cannot un << 2116 $state = STATE_NORMAL; << 2117 } << 2118 } << 2119 << 2120 << 2121 # << 2122 # STATE_BODY and STATE_BODY_MAYBE: the bulk o << 2123 # << 2124 sub process_body($$) { << 2125 my $file = shift; << 2126 << 2127 if ($state == STATE_BODY_WITH_BLANK_LINE << 2128 dump_section($file, $section, $conten << 2129 $section = $section_default; << 2130 $new_start_line = $.; << 2131 $contents = ""; << 2132 } << 2133 << 2134 if (/$doc_sect/i) { # case insensitive fo << 2135 $in_doc_sect = 1; << 2136 $newsection = $1; << 2137 $newcontents = $2; << 2138 << 2139 # map the supported section names to << 2140 if ($newsection =~ m/^description$/i) << 2141 $newsection = $section_default; << 2142 } elsif ($newsection =~ m/^context$/i << 2143 $newsection = $section_context; << 2144 } elsif ($newsection =~ m/^returns?$/ << 2145 $newsection = $section_return; << 2146 } elsif ($newsection =~ m/^\@return$/ << 2147 # special: @return is a section, << 2148 $newsection = $section_return; << 2149 } << 2150 << 2151 if (($contents ne "") && ($contents n << 2152 if (!$in_doc_sect && $Wcontents_b << 2153 emit_warning("${file}:$.", "c << 2154 } << 2155 dump_section($file, $section, $co << 2156 $section = $section_default; << 2157 } << 2158 << 2159 $in_doc_sect = 1; << 2160 $state = STATE_BODY; << 2161 $contents = $newcontents; << 2162 $new_start_line = $.; << 2163 while (substr($contents, 0, 1) eq " " << 2164 $contents = substr($contents, 1); << 2165 } << 2166 if ($contents ne "") { << 2167 $contents .= "\n"; << 2168 } << 2169 $section = $newsection; << 2170 $leading_space = undef; << 2171 } elsif (/$doc_end/) { << 2172 if (($contents ne "") && ($contents n << 2173 dump_section($file, $section, $co << 2174 $section = $section_default; << 2175 $contents = ""; << 2176 } << 2177 # look for doc_com + <text> + doc_end << 2178 if ($_ =~ m'\s*\*\s*[a-zA-Z_0-9:\.]+\ << 2179 emit_warning("${file}:$.", "suspi << 2180 } << 2181 << 2182 $prototype = ""; << 2183 $state = STATE_PROTO; << 2184 $brcount = 0; << 2185 $new_start_line = $. + 1; << 2186 } elsif (/$doc_content/) { << 2187 if ($1 eq "") { << 2188 if ($section eq $section_context) << 2189 dump_section($file, $section, << 2190 $section = $section_default; << 2191 $contents = ""; << 2192 $new_start_line = $.; << 2193 $state = STATE_BODY; << 2194 } else { << 2195 if ($section ne $section_defa << 2196 $state = STATE_BODY_WITH_ << 2197 } else { << 2198 $state = STATE_BODY; << 2199 } << 2200 $contents .= "\n"; << 2201 } << 2202 } elsif ($state == STATE_BODY_MAYBE) << 2203 # Continued declaration purpose << 2204 chomp($declaration_purpose); << 2205 $declaration_purpose .= " " . $1; << 2206 $declaration_purpose =~ s/\s+/ /g << 2207 } else { << 2208 my $cont = $1; << 2209 if ($section =~ m/^@/ || $section << 2210 if (!defined $leading_space) << 2211 if ($cont =~ m/^(\s+)/) { << 2212 $leading_space = $1; << 2213 } else { << 2214 $leading_space = ""; << 2215 } << 2216 } << 2217 $cont =~ s/^$leading_space//; << 2218 } << 2219 $contents .= $cont . "\n"; << 2220 } << 2221 } else { << 2222 # i dont know - bad line? ignore. << 2223 emit_warning("${file}:$.", "bad line: << 2224 } << 2225 } << 2226 << 2227 << 2228 # << 2229 # STATE_PROTO: reading a function/whatever pr << 2230 # << 2231 sub process_proto($$) { << 2232 my $file = shift; << 2233 << 2234 if (/$doc_inline_oneline/) { << 2235 $section = $1; << 2236 $contents = $2; << 2237 if ($contents ne "") { << 2238 $contents .= "\n"; << 2239 dump_section($file, $section, $co << 2240 $section = $section_default; << 2241 $contents = ""; << 2242 } << 2243 } elsif (/$doc_inline_start/) { << 2244 $state = STATE_INLINE; << 2245 $inline_doc_state = STATE_INLINE_NAME << 2246 } elsif ($decl_type eq 'function') { << 2247 process_proto_function($_, $file); << 2248 } else { << 2249 process_proto_type($_, $file); << 2250 } << 2251 } << 2252 << 2253 # << 2254 # STATE_DOCBLOCK: within a DOC: block. << 2255 # << 2256 sub process_docblock($$) { << 2257 my $file = shift; << 2258 << 2259 if (/$doc_end/) { << 2260 dump_doc_section($file, $section, $co << 2261 $section = $section_default; << 2262 $contents = ""; << 2263 $function = ""; << 2264 %parameterdescs = (); << 2265 %parametertypes = (); << 2266 @parameterlist = (); << 2267 %sections = (); << 2268 @sectionlist = (); << 2269 $prototype = ""; << 2270 $state = STATE_NORMAL; << 2271 } elsif (/$doc_content/) { << 2272 if ( $1 eq "" ) { << 2273 $contents .= $blankline; << 2274 } else { << 2275 $contents .= $1 . "\n"; << 2276 } << 2277 } << 2278 } << 2279 << 2280 # << 2281 # STATE_INLINE: docbook comments within a pro << 2282 # << 2283 sub process_inline($$) { << 2284 my $file = shift; << 2285 << 2286 # First line (state 1) needs to be a @par << 2287 if ($inline_doc_state == STATE_INLINE_NAM << 2288 $section = $1; << 2289 $contents = $2; << 2290 $new_start_line = $.; << 2291 if ($contents ne "") { << 2292 while (substr($contents, 0, 1) eq << 2293 $contents = substr($contents, << 2294 } << 2295 $contents .= "\n"; << 2296 } << 2297 $inline_doc_state = STATE_INLINE_TEXT << 2298 # Documentation block end */ << 2299 } elsif (/$doc_inline_end/) { << 2300 if (($contents ne "") && ($contents n << 2301 dump_section($file, $section, $co << 2302 $section = $section_default; << 2303 $contents = ""; << 2304 } << 2305 $state = STATE_PROTO; << 2306 $inline_doc_state = STATE_INLINE_NA; << 2307 # Regular text << 2308 } elsif (/$doc_content/) { << 2309 if ($inline_doc_state == STATE_INLINE << 2310 $contents .= $1 . "\n"; << 2311 # nuke leading blank lines << 2312 if ($contents =~ /^\s*$/) { << 2313 $contents = ""; << 2314 } << 2315 } elsif ($inline_doc_state == STATE_I << 2316 $inline_doc_state = STATE_INLINE_ << 2317 emit_warning("${file}:$.", "Incor << 2318 } << 2319 } << 2320 } << 2321 << 2322 << 2323 sub process_file($) { 2802 sub process_file($) { 2324 my $file; 2803 my $file; >> 2804 my $identifier; >> 2805 my $func; >> 2806 my $descr; >> 2807 my $in_purpose = 0; 2325 my $initial_section_counter = $section_co 2808 my $initial_section_counter = $section_counter; 2326 my ($orig_file) = @_; 2809 my ($orig_file) = @_; >> 2810 my $leading_space; 2327 2811 2328 $file = map_filename($orig_file); 2812 $file = map_filename($orig_file); 2329 2813 2330 if (!open(IN_FILE,"<$file")) { !! 2814 if (!open(IN,"<$file")) { 2331 print STDERR "Error: Cannot open file !! 2815 print STDERR "Error: Cannot open file $file\n"; 2332 ++$errors; !! 2816 ++$errors; 2333 return; !! 2817 return; 2334 } 2818 } 2335 2819 2336 $. = 1; 2820 $. = 1; 2337 2821 2338 $section_counter = 0; 2822 $section_counter = 0; 2339 while (<IN_FILE>) { !! 2823 while (<IN>) { 2340 while (!/^ \*/ && s/\\\s*$//) { !! 2824 while (s/\\\s*$//) { 2341 $_ .= <IN_FILE>; !! 2825 $_ .= <IN>; 2342 } !! 2826 } 2343 # Replace tabs by spaces !! 2827 if ($state == STATE_NORMAL) { 2344 while ($_ =~ s/\t+/' ' x (length($&) !! 2828 if (/$doc_start/o) { 2345 # Hand this line to the appropriate s !! 2829 $state = STATE_NAME; # next line is always the function name 2346 if ($state == STATE_NORMAL) { !! 2830 $in_doc_sect = 0; 2347 process_normal(); !! 2831 $declaration_start_line = $. + 1; 2348 } elsif ($state == STATE_NAME) { !! 2832 } 2349 process_name($file, $_); !! 2833 } elsif ($state == STATE_NAME) {# this line is the function name (always) 2350 } elsif ($state == STATE_BODY || $sta !! 2834 if (/$doc_block/o) { 2351 $state == STATE_BODY_WITH_BL !! 2835 $state = STATE_DOCBLOCK; 2352 process_body($file, $_); !! 2836 $contents = ""; 2353 } elsif ($state == STATE_INLINE) { # !! 2837 $new_start_line = $. + 1; 2354 process_inline($file, $_); !! 2838 2355 } elsif ($state == STATE_PROTO) { !! 2839 if ( $1 eq "" ) { 2356 process_proto($file, $_); !! 2840 $section = $section_intro; 2357 } elsif ($state == STATE_DOCBLOCK) { !! 2841 } else { 2358 process_docblock($file, $_); !! 2842 $section = $1; 2359 } !! 2843 } 2360 } !! 2844 } 2361 !! 2845 elsif (/$doc_decl/o) { 2362 # Make sure we got something interesting. !! 2846 $identifier = $1; 2363 if ($initial_section_counter == $section_ !! 2847 if (/\s*([\w\s]+?)\s*-/) { 2364 output_mode ne "none") { !! 2848 $identifier = $1; 2365 if ($output_selection == OUTPUT_INCLU !! 2849 } 2366 emit_warning("${file}:1", "'$_' n !! 2850 2367 for keys %function_table; !! 2851 $state = STATE_FIELD; 2368 } else { !! 2852 # if there's no @param blocks need to set up default section 2369 emit_warning("${file}:1", "no str !! 2853 # here 2370 } !! 2854 $contents = ""; >> 2855 $section = $section_default; >> 2856 $new_start_line = $. + 1; >> 2857 if (/-(.*)/) { >> 2858 # strip leading/trailing/multiple spaces >> 2859 $descr= $1; >> 2860 $descr =~ s/^\s*//; >> 2861 $descr =~ s/\s*$//; >> 2862 $descr =~ s/\s+/ /g; >> 2863 $declaration_purpose = xml_escape($descr); >> 2864 $in_purpose = 1; >> 2865 } else { >> 2866 $declaration_purpose = ""; >> 2867 } >> 2868 >> 2869 if (($declaration_purpose eq "") && $verbose) { >> 2870 print STDERR "${file}:$.: warning: missing initial short description on line:\n"; >> 2871 print STDERR $_; >> 2872 ++$warnings; >> 2873 } >> 2874 >> 2875 if ($identifier =~ m/^struct/) { >> 2876 $decl_type = 'struct'; >> 2877 } elsif ($identifier =~ m/^union/) { >> 2878 $decl_type = 'union'; >> 2879 } elsif ($identifier =~ m/^enum/) { >> 2880 $decl_type = 'enum'; >> 2881 } elsif ($identifier =~ m/^typedef/) { >> 2882 $decl_type = 'typedef'; >> 2883 } else { >> 2884 $decl_type = 'function'; >> 2885 } >> 2886 >> 2887 if ($verbose) { >> 2888 print STDERR "${file}:$.: info: Scanning doc for $identifier\n"; >> 2889 } >> 2890 } else { >> 2891 print STDERR "${file}:$.: warning: Cannot understand $_ on line $.", >> 2892 " - I thought it was a doc line\n"; >> 2893 ++$warnings; >> 2894 $state = STATE_NORMAL; >> 2895 } >> 2896 } elsif ($state == STATE_FIELD) { # look for head: lines, and include content >> 2897 if (/$doc_sect/i) { # case insensitive for supported section names >> 2898 $newsection = $1; >> 2899 $newcontents = $2; >> 2900 >> 2901 # map the supported section names to the canonical names >> 2902 if ($newsection =~ m/^description$/i) { >> 2903 $newsection = $section_default; >> 2904 } elsif ($newsection =~ m/^context$/i) { >> 2905 $newsection = $section_context; >> 2906 } elsif ($newsection =~ m/^returns?$/i) { >> 2907 $newsection = $section_return; >> 2908 } elsif ($newsection =~ m/^\@return$/) { >> 2909 # special: @return is a section, not a param description >> 2910 $newsection = $section_return; >> 2911 } >> 2912 >> 2913 if (($contents ne "") && ($contents ne "\n")) { >> 2914 if (!$in_doc_sect && $verbose) { >> 2915 print STDERR "${file}:$.: warning: contents before sections\n"; >> 2916 ++$warnings; >> 2917 } >> 2918 dump_section($file, $section, xml_escape($contents)); >> 2919 $section = $section_default; >> 2920 } >> 2921 >> 2922 $in_doc_sect = 1; >> 2923 $in_purpose = 0; >> 2924 $contents = $newcontents; >> 2925 $new_start_line = $.; >> 2926 while ((substr($contents, 0, 1) eq " ") || >> 2927 substr($contents, 0, 1) eq "\t") { >> 2928 $contents = substr($contents, 1); >> 2929 } >> 2930 if ($contents ne "") { >> 2931 $contents .= "\n"; >> 2932 } >> 2933 $section = $newsection; >> 2934 $leading_space = undef; >> 2935 } elsif (/$doc_end/) { >> 2936 if (($contents ne "") && ($contents ne "\n")) { >> 2937 dump_section($file, $section, xml_escape($contents)); >> 2938 $section = $section_default; >> 2939 $contents = ""; >> 2940 } >> 2941 # look for doc_com + <text> + doc_end: >> 2942 if ($_ =~ m'\s*\*\s*[a-zA-Z_0-9:\.]+\*/') { >> 2943 print STDERR "${file}:$.: warning: suspicious ending line: $_"; >> 2944 ++$warnings; >> 2945 } >> 2946 >> 2947 $prototype = ""; >> 2948 $state = STATE_PROTO; >> 2949 $brcount = 0; >> 2950 # print STDERR "end of doc comment, looking for prototype\n"; >> 2951 } elsif (/$doc_content/) { >> 2952 # miguel-style comment kludge, look for blank lines after >> 2953 # @parameter line to signify start of description >> 2954 if ($1 eq "") { >> 2955 if ($section =~ m/^@/ || $section eq $section_context) { >> 2956 dump_section($file, $section, xml_escape($contents)); >> 2957 $section = $section_default; >> 2958 $contents = ""; >> 2959 $new_start_line = $.; >> 2960 } else { >> 2961 $contents .= "\n"; >> 2962 } >> 2963 $in_purpose = 0; >> 2964 } elsif ($in_purpose == 1) { >> 2965 # Continued declaration purpose >> 2966 chomp($declaration_purpose); >> 2967 $declaration_purpose .= " " . xml_escape($1); >> 2968 $declaration_purpose =~ s/\s+/ /g; >> 2969 } else { >> 2970 my $cont = $1; >> 2971 if ($section =~ m/^@/ || $section eq $section_context) { >> 2972 if (!defined $leading_space) { >> 2973 if ($cont =~ m/^(\s+)/) { >> 2974 $leading_space = $1; >> 2975 } else { >> 2976 $leading_space = ""; >> 2977 } >> 2978 } >> 2979 >> 2980 $cont =~ s/^$leading_space//; >> 2981 } >> 2982 $contents .= $cont . "\n"; >> 2983 } >> 2984 } else { >> 2985 # i dont know - bad line? ignore. >> 2986 print STDERR "${file}:$.: warning: bad line: $_"; >> 2987 ++$warnings; >> 2988 } >> 2989 } elsif ($state == STATE_INLINE) { # scanning for inline parameters >> 2990 # First line (state 1) needs to be a @parameter >> 2991 if ($inline_doc_state == STATE_INLINE_NAME && /$doc_inline_sect/o) { >> 2992 $section = $1; >> 2993 $contents = $2; >> 2994 $new_start_line = $.; >> 2995 if ($contents ne "") { >> 2996 while ((substr($contents, 0, 1) eq " ") || >> 2997 substr($contents, 0, 1) eq "\t") { >> 2998 $contents = substr($contents, 1); >> 2999 } >> 3000 $contents .= "\n"; >> 3001 } >> 3002 $inline_doc_state = STATE_INLINE_TEXT; >> 3003 # Documentation block end */ >> 3004 } elsif (/$doc_inline_end/) { >> 3005 if (($contents ne "") && ($contents ne "\n")) { >> 3006 dump_section($file, $section, xml_escape($contents)); >> 3007 $section = $section_default; >> 3008 $contents = ""; >> 3009 } >> 3010 $state = STATE_PROTO; >> 3011 $inline_doc_state = STATE_INLINE_NA; >> 3012 # Regular text >> 3013 } elsif (/$doc_content/) { >> 3014 if ($inline_doc_state == STATE_INLINE_TEXT) { >> 3015 $contents .= $1 . "\n"; >> 3016 # nuke leading blank lines >> 3017 if ($contents =~ /^\s*$/) { >> 3018 $contents = ""; >> 3019 } >> 3020 } elsif ($inline_doc_state == STATE_INLINE_NAME) { >> 3021 $inline_doc_state = STATE_INLINE_ERROR; >> 3022 print STDERR "${file}:$.: warning: "; >> 3023 print STDERR "Incorrect use of kernel-doc format: $_"; >> 3024 ++$warnings; >> 3025 } >> 3026 } >> 3027 } elsif ($state == STATE_PROTO) { # scanning for function '{' (end of prototype) >> 3028 if (/$doc_inline_oneline/) { >> 3029 $section = $1; >> 3030 $contents = $2; >> 3031 if ($contents ne "") { >> 3032 $contents .= "\n"; >> 3033 dump_section($file, $section, xml_escape($contents)); >> 3034 $section = $section_default; >> 3035 $contents = ""; >> 3036 } >> 3037 } elsif (/$doc_inline_start/) { >> 3038 $state = STATE_INLINE; >> 3039 $inline_doc_state = STATE_INLINE_NAME; >> 3040 } elsif ($decl_type eq 'function') { >> 3041 process_proto_function($_, $file); >> 3042 } else { >> 3043 process_proto_type($_, $file); >> 3044 } >> 3045 } elsif ($state == STATE_DOCBLOCK) { >> 3046 if (/$doc_end/) >> 3047 { >> 3048 dump_doc_section($file, $section, xml_escape($contents)); >> 3049 $section = $section_default; >> 3050 $contents = ""; >> 3051 $function = ""; >> 3052 %parameterdescs = (); >> 3053 %parametertypes = (); >> 3054 @parameterlist = (); >> 3055 %sections = (); >> 3056 @sectionlist = (); >> 3057 $prototype = ""; >> 3058 $state = STATE_NORMAL; >> 3059 } >> 3060 elsif (/$doc_content/) >> 3061 { >> 3062 if ( $1 eq "" ) >> 3063 { >> 3064 $contents .= $blankline; >> 3065 } >> 3066 else >> 3067 { >> 3068 $contents .= $1 . "\n"; >> 3069 } >> 3070 } >> 3071 } >> 3072 } >> 3073 if ($initial_section_counter == $section_counter) { >> 3074 print STDERR "${file}:1: warning: no structured comments found\n"; >> 3075 if (($output_selection == OUTPUT_INCLUDE) && ($show_not_found == 1)) { >> 3076 print STDERR " Was looking for '$_'.\n" for keys %function_table; >> 3077 } >> 3078 if ($output_mode eq "xml") { >> 3079 # The template wants at least one RefEntry here; make one. >> 3080 print "<refentry>\n"; >> 3081 print " <refnamediv>\n"; >> 3082 print " <refname>\n"; >> 3083 print " ${orig_file}\n"; >> 3084 print " </refname>\n"; >> 3085 print " <refpurpose>\n"; >> 3086 print " Document generation inconsistency\n"; >> 3087 print " </refpurpose>\n"; >> 3088 print " </refnamediv>\n"; >> 3089 print " <refsect1>\n"; >> 3090 print " <title>\n"; >> 3091 print " Oops\n"; >> 3092 print " </title>\n"; >> 3093 print " <warning>\n"; >> 3094 print " <para>\n"; >> 3095 print " The template for this document tried to insert\n"; >> 3096 print " the structured comment from the file\n"; >> 3097 print " <filename>${orig_file}</filename> at this point,\n"; >> 3098 print " but none was found.\n"; >> 3099 print " This dummy section is inserted to allow\n"; >> 3100 print " generation to continue.\n"; >> 3101 print " </para>\n"; >> 3102 print " </warning>\n"; >> 3103 print " </refsect1>\n"; >> 3104 print "</refentry>\n"; >> 3105 } 2371 } 3106 } 2372 close IN_FILE; << 2373 } 3107 } 2374 3108 2375 3109 2376 if ($output_mode eq "rst") { << 2377 get_sphinx_version() if (!$sphinx_major); << 2378 } << 2379 << 2380 $kernelversion = get_kernel_version(); 3110 $kernelversion = get_kernel_version(); 2381 3111 2382 # generate a sequence of code that will splic 3112 # generate a sequence of code that will splice in highlighting information 2383 # using the s// operator. 3113 # using the s// operator. 2384 for (my $k = 0; $k < @highlights; $k++) { 3114 for (my $k = 0; $k < @highlights; $k++) { 2385 my $pattern = $highlights[$k][0]; 3115 my $pattern = $highlights[$k][0]; 2386 my $result = $highlights[$k][1]; 3116 my $result = $highlights[$k][1]; 2387 # print STDERR "scanning pattern:$pattern, 3117 # print STDERR "scanning pattern:$pattern, highlight:($result)\n"; 2388 $dohighlight .= "\$contents =~ s:$patter 3118 $dohighlight .= "\$contents =~ s:$pattern:$result:gs;\n"; 2389 } 3119 } 2390 3120 2391 # Read the file that maps relative names to a 3121 # Read the file that maps relative names to absolute names for 2392 # separate source and object directories and 3122 # separate source and object directories and for shadow trees. 2393 if (open(SOURCE_MAP, "<.tmp_filelist.txt")) { 3123 if (open(SOURCE_MAP, "<.tmp_filelist.txt")) { 2394 my ($relname, $absname); !! 3124 my ($relname, $absname); 2395 while(<SOURCE_MAP>) { !! 3125 while(<SOURCE_MAP>) { 2396 chop(); !! 3126 chop(); 2397 ($relname, $absname) = (split())[0..1 !! 3127 ($relname, $absname) = (split())[0..1]; 2398 $relname =~ s:^/+::; !! 3128 $relname =~ s:^/+::; 2399 $source_map{$relname} = $absname; !! 3129 $source_map{$relname} = $absname; 2400 } !! 3130 } 2401 close(SOURCE_MAP); !! 3131 close(SOURCE_MAP); 2402 } 3132 } 2403 3133 2404 if ($output_selection == OUTPUT_EXPORTED || 3134 if ($output_selection == OUTPUT_EXPORTED || 2405 $output_selection == OUTPUT_INTERNAL) { 3135 $output_selection == OUTPUT_INTERNAL) { 2406 3136 2407 push(@export_file_list, @ARGV); 3137 push(@export_file_list, @ARGV); 2408 3138 2409 foreach (@export_file_list) { 3139 foreach (@export_file_list) { 2410 chomp; !! 3140 chomp; 2411 process_export_file($_); !! 3141 process_export_file($_); 2412 } 3142 } 2413 } 3143 } 2414 3144 2415 foreach (@ARGV) { 3145 foreach (@ARGV) { 2416 chomp; 3146 chomp; 2417 process_file($_); 3147 process_file($_); 2418 } 3148 } 2419 if ($verbose && $errors) { 3149 if ($verbose && $errors) { 2420 print STDERR "$errors errors\n"; !! 3150 print STDERR "$errors errors\n"; 2421 } 3151 } 2422 if ($verbose && $warnings) { 3152 if ($verbose && $warnings) { 2423 print STDERR "$warnings warnings\n"; !! 3153 print STDERR "$warnings warnings\n"; 2424 } << 2425 << 2426 if ($Werror && $warnings) { << 2427 print STDERR "$warnings warnings as Error << 2428 exit($warnings); << 2429 } else { << 2430 exit($output_mode eq "none" ? 0 : $errors << 2431 } 3154 } 2432 3155 2433 __END__ !! 3156 exit($errors); 2434 << 2435 =head1 OPTIONS << 2436 << 2437 =head2 Output format selection (mutually excl << 2438 << 2439 =over 8 << 2440 << 2441 =item -man << 2442 << 2443 Output troff manual page format. << 2444 << 2445 =item -rst << 2446 << 2447 Output reStructuredText format. This is the d << 2448 << 2449 =item -none << 2450 << 2451 Do not output documentation, only warnings. << 2452 << 2453 =back << 2454 << 2455 =head2 Output format modifiers << 2456 << 2457 =head3 reStructuredText only << 2458 << 2459 =over 8 << 2460 << 2461 =item -sphinx-version VERSION << 2462 << 2463 Use the ReST C domain dialect compatible with << 2464 << 2465 If not specified, kernel-doc will auto-detect << 2466 found on PATH. << 2467 << 2468 =back << 2469 << 2470 =head2 Output selection (mutually exclusive): << 2471 << 2472 =over 8 << 2473 << 2474 =item -export << 2475 << 2476 Only output documentation for the symbols tha << 2477 EXPORT_SYMBOL() and related macros in any inp << 2478 << 2479 =item -internal << 2480 << 2481 Only output documentation for the symbols tha << 2482 EXPORT_SYMBOL() and related macros in any inp << 2483 << 2484 =item -function NAME << 2485 << 2486 Only output documentation for the given funct << 2487 All other functions and DOC: sections are ign << 2488 << 2489 May be specified multiple times. << 2490 << 2491 =item -nosymbol NAME << 2492 << 2493 Exclude the specified symbol from the output << 2494 << 2495 May be specified multiple times. << 2496 << 2497 =back << 2498 << 2499 =head2 Output selection modifiers: << 2500 << 2501 =over 8 << 2502 << 2503 =item -no-doc-sections << 2504 << 2505 Do not output DOC: sections. << 2506 << 2507 =item -export-file FILE << 2508 << 2509 Specify an additional FILE in which to look f << 2510 << 2511 To be used with -export or -internal. << 2512 << 2513 May be specified multiple times. << 2514 << 2515 =back << 2516 << 2517 =head3 reStructuredText only << 2518 << 2519 =over 8 << 2520 << 2521 =item -enable-lineno << 2522 << 2523 Enable output of .. LINENO lines. << 2524 << 2525 =back << 2526 << 2527 =head2 Other parameters: << 2528 << 2529 =over 8 << 2530 << 2531 =item -h, -help << 2532 << 2533 Print this help. << 2534 << 2535 =item -v << 2536 << 2537 Verbose output, more warnings and other infor << 2538 << 2539 =item -Werror << 2540 << 2541 Treat warnings as errors. << 2542 << 2543 =back << 2544 << 2545 =cut <<
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.