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