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