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