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