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