home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6-686 / scripts / kernel-doc < prev    next >
Encoding:
Text File  |  2006-08-11  |  50.4 KB  |  1,884 lines

  1. #!/usr/bin/perl -w
  2.  
  3. use 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. ##                                  ##
  9. ## #define enhancements by Armin Kuster <akuster@mvista.com>     ##
  10. ## Copyright (c) 2000 MontaVista Software, Inc.             ##
  11. ##                                  ##
  12. ## This software falls under the GNU General Public License.     ##
  13. ## Please read the COPYING file for more information             ##
  14.  
  15. # w.o. 03-11-2000: added the '-filelist' option.
  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.  
  40. #
  41. # This will read a 'c' file and scan for embedded comments in the
  42. # style of gnome comments (+minor extensions - see below).
  43. #
  44.  
  45. # Note: This only supports 'c'.
  46.  
  47. # usage:
  48. # kernel-doc [ -docbook | -html | -text | -man ]
  49. #           [ -function funcname [ -function funcname ...] ] c file(s)s > outputfile
  50. # or
  51. #           [ -nofunction funcname [ -function funcname ...] ] c file(s)s > outputfile
  52. #
  53. #  Set output format using one of -docbook -html -text or -man.  Default is man.
  54. #
  55. #  -function funcname
  56. #    If set, then only generate documentation for the given function(s).  All
  57. #    other functions are ignored.
  58. #
  59. #  -nofunction funcname
  60. #    If set, then only generate documentation for the other function(s).  All
  61. #    other functions are ignored. Cannot be used with -function together
  62. #    (yes, that's a bug -- perl hackers can fix it 8))
  63. #
  64. #  c files - list of 'c' files to process
  65. #
  66. #  All output goes to stdout, with errors to stderr.
  67.  
  68. #
  69. # format of comments.
  70. # In the following table, (...)? signifies optional structure.
  71. #                         (...)* signifies 0 or more structure elements
  72. # /**
  73. #  * function_name(:)? (- short description)?
  74. # (* @parameterx: (description of parameter x)?)*
  75. # (* a blank line)?
  76. #  * (Description:)? (Description of function)?
  77. #  * (section header: (section description)? )*
  78. #  (*)?*/
  79. #
  80. # So .. the trivial example would be:
  81. #
  82. # /**
  83. #  * my_function
  84. #  **/
  85. #
  86. # If the Description: header tag is ommitted, then there must be a blank line
  87. # after the last parameter specification.
  88. # e.g.
  89. # /**
  90. #  * my_function - does my stuff
  91. #  * @my_arg: its mine damnit
  92. #  *
  93. #  * Does my stuff explained.
  94. #  */
  95. #
  96. #  or, could also use:
  97. # /**
  98. #  * my_function - does my stuff
  99. #  * @my_arg: its mine damnit
  100. #  * Description: Does my stuff explained.
  101. #  */
  102. # etc.
  103. #
  104. # Beside functions you can also write documentation for structs, unions,
  105. # enums and typedefs. Instead of the function name you must write the name
  106. # of the declaration;  the struct/union/enum/typedef must always precede
  107. # the name. Nesting of declarations is not supported.
  108. # Use the argument mechanism to document members or constants.
  109. # e.g.
  110. # /**
  111. #  * struct my_struct - short description
  112. #  * @a: first member
  113. #  * @b: second member
  114. #  *
  115. #  * Longer description
  116. #  */
  117. # struct my_struct {
  118. #     int a;
  119. #     int b;
  120. # /* private: */
  121. #     int c;
  122. # };
  123. #
  124. # All descriptions can be multiline, except the short function description.
  125. #
  126. # You can also add additional sections. When documenting kernel functions you
  127. # should document the "Context:" of the function, e.g. whether the functions
  128. # can be called form interrupts. Unlike other sections you can end it with an
  129. # empty line.
  130. # Example-sections should contain the string EXAMPLE so that they are marked
  131. # appropriately in DocBook.
  132. #
  133. # Example:
  134. # /**
  135. #  * user_function - function that can only be called in user context
  136. #  * @a: some argument
  137. #  * Context: !in_interrupt()
  138. #  *
  139. #  * Some description
  140. #  * Example:
  141. #  *    user_function(22);
  142. #  */
  143. # ...
  144. #
  145. #
  146. # All descriptive text is further processed, scanning for the following special
  147. # patterns, which are highlighted appropriately.
  148. #
  149. # 'funcname()' - function
  150. # '$ENVVAR' - environmental variable
  151. # '&struct_name' - name of a structure (up to two words including 'struct')
  152. # '@parameter' - name of a parameter
  153. # '%CONST' - name of a constant.
  154.  
  155. my $errors = 0;
  156. my $warnings = 0;
  157.  
  158. # match expressions used to find embedded type information
  159. my $type_constant = '\%([-_\w]+)';
  160. my $type_func = '(\w+)\(\)';
  161. my $type_param = '\@(\w+)';
  162. my $type_struct = '\&((struct\s*)?[_\w]+)';
  163. my $type_env = '(\$\w+)';
  164.  
  165. # Output conversion substitutions.
  166. #  One for each output format
  167.  
  168. # these work fairly well
  169. my %highlights_html = ( $type_constant, "<i>\$1</i>",
  170.             $type_func, "<b>\$1</b>",
  171.             $type_struct, "<i>\$1</i>",
  172.             $type_param, "<tt><b>\$1</b></tt>" );
  173. my $blankline_html = "<p>";
  174.  
  175. # XML, docbook format
  176. my %highlights_xml = ( "([^=])\\\"([^\\\"<]+)\\\"", "\$1<quote>\$2</quote>",
  177.             $type_constant, "<constant>\$1</constant>",
  178.             $type_func, "<function>\$1</function>",
  179.             $type_struct, "<structname>\$1</structname>",
  180.             $type_env, "<envar>\$1</envar>",
  181.             $type_param, "<parameter>\$1</parameter>" );
  182. my $blankline_xml = "</para><para>\n";
  183.  
  184. # gnome, docbook format
  185. my %highlights_gnome = ( $type_constant, "<replaceable class=\"option\">\$1</replaceable>",
  186.              $type_func, "<function>\$1</function>",
  187.              $type_struct, "<structname>\$1</structname>",
  188.              $type_env, "<envar>\$1</envar>",
  189.              $type_param, "<parameter>\$1</parameter>" );
  190. my $blankline_gnome = "</para><para>\n";
  191.  
  192. # these are pretty rough
  193. my %highlights_man = ( $type_constant, "\$1",
  194.                $type_func, "\\\\fB\$1\\\\fP",
  195.                $type_struct, "\\\\fI\$1\\\\fP",
  196.                $type_param, "\\\\fI\$1\\\\fP" );
  197. my $blankline_man = "";
  198.  
  199. # text-mode
  200. my %highlights_text = ( $type_constant, "\$1",
  201.             $type_func, "\$1",
  202.             $type_struct, "\$1",
  203.             $type_param, "\$1" );
  204. my $blankline_text = "";
  205.  
  206.  
  207. sub usage {
  208.     print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man ]\n";
  209.     print "         [ -function funcname [ -function funcname ...] ]\n";
  210.     print "         [ -nofunction funcname [ -nofunction funcname ...] ]\n";
  211.     print "         c source file(s) > outputfile\n";
  212.     exit 1;
  213. }
  214.  
  215. # read arguments
  216. if ($#ARGV==-1) {
  217.     usage();
  218. }
  219.  
  220. my $verbose = 0;
  221. my $output_mode = "man";
  222. my %highlights = %highlights_man;
  223. my $blankline = $blankline_man;
  224. my $modulename = "Kernel API";
  225. my $function_only = 0;
  226. my $man_date = ('January', 'February', 'March', 'April', 'May', 'June',
  227.         'July', 'August', 'September', 'October',
  228.         'November', 'December')[(localtime)[4]] .
  229.   " " . ((localtime)[5]+1900);
  230.  
  231. # Essentially these are globals
  232. # They probably want to be tidied up made more localised or summat.
  233. # CAVEAT EMPTOR!  Some of the others I localised may not want to be which
  234. # could cause "use of undefined value" or other bugs.
  235. my ($function, %function_table,%parametertypes,$declaration_purpose);
  236. my ($type,$declaration_name,$return_type);
  237. my ($newsection,$newcontents,$prototype,$filelist, $brcount, %source_map);
  238.  
  239. # Generated docbook code is inserted in a template at a point where
  240. # docbook v3.1 requires a non-zero sequence of RefEntry's; see:
  241. # http://www.oasis-open.org/docbook/documentation/reference/html/refentry.html
  242. # We keep track of number of generated entries and generate a dummy
  243. # if needs be to ensure the expanded template can be postprocessed
  244. # into html.
  245. my $section_counter = 0;
  246.  
  247. my $lineprefix="";
  248.  
  249. # states
  250. # 0 - normal code
  251. # 1 - looking for function name
  252. # 2 - scanning field start.
  253. # 3 - scanning prototype.
  254. # 4 - documentation block
  255. my $state;
  256.  
  257. #declaration types: can be
  258. # 'function', 'struct', 'union', 'enum', 'typedef'
  259. my $decl_type;
  260.  
  261. my $doc_special = "\@\%\$\&";
  262.  
  263. my $doc_start = '^/\*\*\s*$'; # Allow whitespace at end of comment start.
  264. my $doc_end = '\*/';
  265. my $doc_com = '\s*\*\s*';
  266. my $doc_decl = $doc_com.'(\w+)';
  267. my $doc_sect = $doc_com.'(['.$doc_special.']?[\w ]+):(.*)';
  268. my $doc_content = $doc_com.'(.*)';
  269. my $doc_block = $doc_com.'DOC:\s*(.*)?';
  270.  
  271. my %constants;
  272. my %parameterdescs;
  273. my @parameterlist;
  274. my %sections;
  275. my @sectionlist;
  276.  
  277. my $contents = "";
  278. my $section_default = "Description";    # default section
  279. my $section_intro = "Introduction";
  280. my $section = $section_default;
  281. my $section_context = "Context";
  282.  
  283. my $undescribed = "-- undescribed --";
  284.  
  285. reset_state();
  286.  
  287. while ($ARGV[0] =~ m/^-(.*)/) {
  288.     my $cmd = shift @ARGV;
  289.     if ($cmd eq "-html") {
  290.     $output_mode = "html";
  291.     %highlights = %highlights_html;
  292.     $blankline = $blankline_html;
  293.     } elsif ($cmd eq "-man") {
  294.     $output_mode = "man";
  295.     %highlights = %highlights_man;
  296.     $blankline = $blankline_man;
  297.     } elsif ($cmd eq "-text") {
  298.     $output_mode = "text";
  299.     %highlights = %highlights_text;
  300.     $blankline = $blankline_text;
  301.     } elsif ($cmd eq "-docbook") {
  302.     $output_mode = "xml";
  303.     %highlights = %highlights_xml;
  304.     $blankline = $blankline_xml;
  305.     } elsif ($cmd eq "-gnome") {
  306.     $output_mode = "gnome";
  307.     %highlights = %highlights_gnome;
  308.     $blankline = $blankline_gnome;
  309.     } elsif ($cmd eq "-module") { # not needed for XML, inherits from calling document
  310.     $modulename = shift @ARGV;
  311.     } elsif ($cmd eq "-function") { # to only output specific functions
  312.     $function_only = 1;
  313.     $function = shift @ARGV;
  314.     $function_table{$function} = 1;
  315.     } elsif ($cmd eq "-nofunction") { # to only output specific functions
  316.     $function_only = 2;
  317.     $function = shift @ARGV;
  318.     $function_table{$function} = 1;
  319.     } elsif ($cmd eq "-v") {
  320.     $verbose = 1;
  321.     } elsif (($cmd eq "-h") || ($cmd eq "--help")) {
  322.     usage();
  323.     } elsif ($cmd eq '-filelist') {
  324.         $filelist = shift @ARGV;
  325.     }
  326. }
  327.  
  328.  
  329. # generate a sequence of code that will splice in highlighting information
  330. # using the s// operator.
  331. my $dohighlight = "";
  332. foreach my $pattern (keys %highlights) {
  333. #    print "scanning pattern $pattern ($highlights{$pattern})\n";
  334.     $dohighlight .=  "\$contents =~ s:$pattern:$highlights{$pattern}:gs;\n";
  335. }
  336.  
  337. ##
  338. # dumps section contents to arrays/hashes intended for that purpose.
  339. #
  340. sub dump_section {
  341.     my $name = shift;
  342.     my $contents = join "\n", @_;
  343.  
  344.     if ($name =~ m/$type_constant/) {
  345.     $name = $1;
  346. #    print STDERR "constant section '$1' = '$contents'\n";
  347.     $constants{$name} = $contents;
  348.     } elsif ($name =~ m/$type_param/) {
  349. #    print STDERR "parameter def '$1' = '$contents'\n";
  350.     $name = $1;
  351.     $parameterdescs{$name} = $contents;
  352.     } else {
  353. #    print STDERR "other section '$name' = '$contents'\n";
  354.     $sections{$name} = $contents;
  355.     push @sectionlist, $name;
  356.     }
  357. }
  358.  
  359. ##
  360. # output function
  361. #
  362. # parameterdescs, a hash.
  363. #  function => "function name"
  364. #  parameterlist => @list of parameters
  365. #  parameterdescs => %parameter descriptions
  366. #  sectionlist => @list of sections
  367. #  sections => %descriont descriptions
  368. #
  369.  
  370. sub output_highlight {
  371.     my $contents = join "\n",@_;
  372.     my $line;
  373.  
  374. #   DEBUG
  375. #   if (!defined $contents) {
  376. #    use Carp;
  377. #    confess "output_highlight got called with no args?\n";
  378. #   }
  379.  
  380.     eval $dohighlight;
  381.     die $@ if $@;
  382.     foreach $line (split "\n", $contents) {
  383.       if ($line eq ""){
  384.         print $lineprefix, $blankline;
  385.     } else {
  386.             $line =~ s/\\\\\\/\&/g;
  387.         print $lineprefix, $line;
  388.     }
  389.     print "\n";
  390.     }
  391. }
  392.  
  393. #output sections in html
  394. sub output_section_html(%) {
  395.     my %args = %{$_[0]};
  396.     my $section;
  397.  
  398.     foreach $section (@{$args{'sectionlist'}}) {
  399.     print "<h3>$section</h3>\n";
  400.     print "<blockquote>\n";
  401.     output_highlight($args{'sections'}{$section});
  402.     print "</blockquote>\n";
  403.     }
  404. }
  405.  
  406. # output enum in html
  407. sub output_enum_html(%) {
  408.     my %args = %{$_[0]};
  409.     my ($parameter);
  410.     my $count;
  411.     print "<h2>enum ".$args{'enum'}."</h2>\n";
  412.  
  413.     print "<b>enum ".$args{'enum'}."</b> {<br>\n";
  414.     $count = 0;
  415.     foreach $parameter (@{$args{'parameterlist'}}) {
  416.         print " <b>".$parameter."</b>";
  417.     if ($count != $#{$args{'parameterlist'}}) {
  418.         $count++;
  419.         print ",\n";
  420.     }
  421.     print "<br>";
  422.     }
  423.     print "};<br>\n";
  424.  
  425.     print "<h3>Constants</h3>\n";
  426.     print "<dl>\n";
  427.     foreach $parameter (@{$args{'parameterlist'}}) {
  428.     print "<dt><b>".$parameter."</b>\n";
  429.     print "<dd>";
  430.     output_highlight($args{'parameterdescs'}{$parameter});
  431.     }
  432.     print "</dl>\n";
  433.     output_section_html(@_);
  434.     print "<hr>\n";
  435. }
  436.  
  437. # output typedef in html
  438. sub output_typedef_html(%) {
  439.     my %args = %{$_[0]};
  440.     my ($parameter);
  441.     my $count;
  442.     print "<h2>typedef ".$args{'typedef'}."</h2>\n";
  443.  
  444.     print "<b>typedef ".$args{'typedef'}."</b>\n";
  445.     output_section_html(@_);
  446.     print "<hr>\n";
  447. }
  448.  
  449. # output struct in html
  450. sub output_struct_html(%) {
  451.     my %args = %{$_[0]};
  452.     my ($parameter);
  453.  
  454.     print "<h2>".$args{'type'}." ".$args{'struct'}."</h2>\n";
  455.     print "<b>".$args{'type'}." ".$args{'struct'}."</b> {<br>\n";
  456.     foreach $parameter (@{$args{'parameterlist'}}) {
  457.     if ($parameter =~ /^#/) {
  458.         print "$parameter<br>\n";
  459.         next;
  460.     }
  461.     my $parameter_name = $parameter;
  462.     $parameter_name =~ s/\[.*//;
  463.  
  464.         ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
  465.     $type = $args{'parametertypes'}{$parameter};
  466.     if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
  467.         # pointer-to-function
  468.         print " <i>$1</i><b>$parameter</b>) <i>($2)</i>;<br>\n";
  469.     } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
  470.         print " <i>$1</i> <b>$parameter</b>$2;<br>\n";
  471.     } else {
  472.         print " <i>$type</i> <b>$parameter</b>;<br>\n";
  473.     }
  474.     }
  475.     print "};<br>\n";
  476.  
  477.     print "<h3>Members</h3>\n";
  478.     print "<dl>\n";
  479.     foreach $parameter (@{$args{'parameterlist'}}) {
  480.     ($parameter =~ /^#/) && next;
  481.  
  482.     my $parameter_name = $parameter;
  483.     $parameter_name =~ s/\[.*//;
  484.  
  485.         ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
  486.     print "<dt><b>".$parameter."</b>\n";
  487.     print "<dd>";
  488.     output_highlight($args{'parameterdescs'}{$parameter_name});
  489.     }
  490.     print "</dl>\n";
  491.     output_section_html(@_);
  492.     print "<hr>\n";
  493. }
  494.  
  495. # output function in html
  496. sub output_function_html(%) {
  497.     my %args = %{$_[0]};
  498.     my ($parameter, $section);
  499.     my $count;
  500.     print "<h2>Function</h2>\n";
  501.  
  502.     print "<i>".$args{'functiontype'}."</i>\n";
  503.     print "<b>".$args{'function'}."</b>\n";
  504.     print "(";
  505.     $count = 0;
  506.     foreach $parameter (@{$args{'parameterlist'}}) {
  507.     $type = $args{'parametertypes'}{$parameter};
  508.     if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
  509.         # pointer-to-function
  510.         print "<i>$1</i><b>$parameter</b>) <i>($2)</i>";
  511.     } else {
  512.         print "<i>".$type."</i> <b>".$parameter."</b>";
  513.     }
  514.     if ($count != $#{$args{'parameterlist'}}) {
  515.         $count++;
  516.         print ",\n";
  517.     }
  518.     }
  519.     print ")\n";
  520.  
  521.     print "<h3>Arguments</h3>\n";
  522.     print "<dl>\n";
  523.     foreach $parameter (@{$args{'parameterlist'}}) {
  524.     my $parameter_name = $parameter;
  525.     $parameter_name =~ s/\[.*//;
  526.  
  527.         ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
  528.     print "<dt><b>".$parameter."</b>\n";
  529.     print "<dd>";
  530.     output_highlight($args{'parameterdescs'}{$parameter_name});
  531.     }
  532.     print "</dl>\n";
  533.     output_section_html(@_);
  534.     print "<hr>\n";
  535. }
  536.  
  537. # output intro in html
  538. sub output_intro_html(%) {
  539.     my %args = %{$_[0]};
  540.     my ($parameter, $section);
  541.     my $count;
  542.  
  543.     foreach $section (@{$args{'sectionlist'}}) {
  544.     print "<h3>$section</h3>\n";
  545.     print "<ul>\n";
  546.     output_highlight($args{'sections'}{$section});
  547.     print "</ul>\n";
  548.     }
  549.     print "<hr>\n";
  550. }
  551.  
  552. sub output_section_xml(%) {
  553.     my %args = %{$_[0]};
  554.     my $section;
  555.     # print out each section
  556.     $lineprefix="   ";
  557.     foreach $section (@{$args{'sectionlist'}}) {
  558.     print "<refsect1>\n";
  559.     print "<title>$section</title>\n";
  560.     if ($section =~ m/EXAMPLE/i) {
  561.         print "<informalexample><programlisting>\n";
  562.     } else {
  563.         print "<para>\n";
  564.     }
  565.     output_highlight($args{'sections'}{$section});
  566.     if ($section =~ m/EXAMPLE/i) {
  567.         print "</programlisting></informalexample>\n";
  568.     } else {
  569.         print "</para>\n";
  570.     }
  571.     print "</refsect1>\n";
  572.     }
  573. }
  574.  
  575. # output function in XML DocBook
  576. sub output_function_xml(%) {
  577.     my %args = %{$_[0]};
  578.     my ($parameter, $section);
  579.     my $count;
  580.     my $id;
  581.  
  582.     $id = "API-".$args{'function'};
  583.     $id =~ s/[^A-Za-z0-9]/-/g;
  584.  
  585.     print "<refentry>\n";
  586.     print "<refentryinfo>\n";
  587.     print " <title>LINUX</title>\n";
  588.     print " <productname>Kernel Hackers Manual</productname>\n";
  589.     print " <date>$man_date</date>\n";
  590.     print "</refentryinfo>\n";
  591.     print "<refmeta>\n";
  592.     print " <refentrytitle><phrase id=\"$id\">".$args{'function'}."</phrase></refentrytitle>\n";
  593.     print " <manvolnum>9</manvolnum>\n";
  594.     print "</refmeta>\n";
  595.     print "<refnamediv>\n";
  596.     print " <refname>".$args{'function'}."</refname>\n";
  597.     print " <refpurpose>\n";
  598.     print "  ";
  599.     output_highlight ($args{'purpose'});
  600.     print " </refpurpose>\n";
  601.     print "</refnamediv>\n";
  602.  
  603.     print "<refsynopsisdiv>\n";
  604.     print " <title>Synopsis</title>\n";
  605.     print "  <funcsynopsis><funcprototype>\n";
  606.     print "   <funcdef>".$args{'functiontype'}." ";
  607.     print "<function>".$args{'function'}." </function></funcdef>\n";
  608.  
  609.     $count = 0;
  610.     if ($#{$args{'parameterlist'}} >= 0) {
  611.     foreach $parameter (@{$args{'parameterlist'}}) {
  612.         $type = $args{'parametertypes'}{$parameter};
  613.         if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
  614.         # pointer-to-function
  615.         print "   <paramdef>$1<parameter>$parameter</parameter>)\n";
  616.         print "     <funcparams>$2</funcparams></paramdef>\n";
  617.         } else {
  618.         print "   <paramdef>".$type;
  619.         print " <parameter>$parameter</parameter></paramdef>\n";
  620.         }
  621.     }
  622.     } else {
  623.     print "  <void/>\n";
  624.     }
  625.     print "  </funcprototype></funcsynopsis>\n";
  626.     print "</refsynopsisdiv>\n";
  627.  
  628.     # print parameters
  629.     print "<refsect1>\n <title>Arguments</title>\n";
  630.     if ($#{$args{'parameterlist'}} >= 0) {
  631.     print " <variablelist>\n";
  632.     foreach $parameter (@{$args{'parameterlist'}}) {
  633.         my $parameter_name = $parameter;
  634.         $parameter_name =~ s/\[.*//;
  635.  
  636.         print "  <varlistentry>\n   <term><parameter>$parameter</parameter></term>\n";
  637.         print "   <listitem>\n    <para>\n";
  638.         $lineprefix="     ";
  639.         output_highlight($args{'parameterdescs'}{$parameter_name});
  640.         print "    </para>\n   </listitem>\n  </varlistentry>\n";
  641.     }
  642.     print " </variablelist>\n";
  643.     } else {
  644.     print " <para>\n  None\n </para>\n";
  645.     }
  646.     print "</refsect1>\n";
  647.  
  648.     output_section_xml(@_);
  649.     print "</refentry>\n\n";
  650. }
  651.  
  652. # output struct in XML DocBook
  653. sub output_struct_xml(%) {
  654.     my %args = %{$_[0]};
  655.     my ($parameter, $section);
  656.     my $id;
  657.  
  658.     $id = "API-struct-".$args{'struct'};
  659.     $id =~ s/[^A-Za-z0-9]/-/g;
  660.  
  661.     print "<refentry>\n";
  662.     print "<refentryinfo>\n";
  663.     print " <title>LINUX</title>\n";
  664.     print " <productname>Kernel Hackers Manual</productname>\n";
  665.     print " <date>$man_date</date>\n";
  666.     print "</refentryinfo>\n";
  667.     print "<refmeta>\n";
  668.     print " <refentrytitle><phrase id=\"$id\">".$args{'type'}." ".$args{'struct'}."</phrase></refentrytitle>\n";
  669.     print " <manvolnum>9</manvolnum>\n";
  670.     print "</refmeta>\n";
  671.     print "<refnamediv>\n";
  672.     print " <refname>".$args{'type'}." ".$args{'struct'}."</refname>\n";
  673.     print " <refpurpose>\n";
  674.     print "  ";
  675.     output_highlight ($args{'purpose'});
  676.     print " </refpurpose>\n";
  677.     print "</refnamediv>\n";
  678.  
  679.     print "<refsynopsisdiv>\n";
  680.     print " <title>Synopsis</title>\n";
  681.     print "  <programlisting>\n";
  682.     print $args{'type'}." ".$args{'struct'}." {\n";
  683.     foreach $parameter (@{$args{'parameterlist'}}) {
  684.     if ($parameter =~ /^#/) {
  685.         print "$parameter\n";
  686.         next;
  687.     }
  688.  
  689.     my $parameter_name = $parameter;
  690.     $parameter_name =~ s/\[.*//;
  691.  
  692.     defined($args{'parameterdescs'}{$parameter_name}) || next;
  693.         ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
  694.     $type = $args{'parametertypes'}{$parameter};
  695.     if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
  696.         # pointer-to-function
  697.         print "  $1 $parameter) ($2);\n";
  698.     } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
  699.         print "  $1 $parameter$2;\n";
  700.     } else {
  701.         print "  ".$type." ".$parameter.";\n";
  702.     }
  703.     }
  704.     print "};";
  705.     print "  </programlisting>\n";
  706.     print "</refsynopsisdiv>\n";
  707.  
  708.     print " <refsect1>\n";
  709.     print "  <title>Members</title>\n";
  710.  
  711.     print "  <variablelist>\n";
  712.     foreach $parameter (@{$args{'parameterlist'}}) {
  713.       ($parameter =~ /^#/) && next;
  714.  
  715.       my $parameter_name = $parameter;
  716.       $parameter_name =~ s/\[.*//;
  717.  
  718.       defined($args{'parameterdescs'}{$parameter_name}) || next;
  719.       ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
  720.       print "    <varlistentry>";
  721.       print "      <term>$parameter</term>\n";
  722.       print "      <listitem><para>\n";
  723.       output_highlight($args{'parameterdescs'}{$parameter_name});
  724.       print "      </para></listitem>\n";
  725.       print "    </varlistentry>\n";
  726.     }
  727.     print "  </variablelist>\n";
  728.     print " </refsect1>\n";
  729.  
  730.     output_section_xml(@_);
  731.  
  732.     print "</refentry>\n\n";
  733. }
  734.  
  735. # output enum in XML DocBook
  736. sub output_enum_xml(%) {
  737.     my %args = %{$_[0]};
  738.     my ($parameter, $section);
  739.     my $count;
  740.     my $id;
  741.  
  742.     $id = "API-enum-".$args{'enum'};
  743.     $id =~ s/[^A-Za-z0-9]/-/g;
  744.  
  745.     print "<refentry>\n";
  746.     print "<refentryinfo>\n";
  747.     print " <title>LINUX</title>\n";
  748.     print " <productname>Kernel Hackers Manual</productname>\n";
  749.     print " <date>$man_date</date>\n";
  750.     print "</refentryinfo>\n";
  751.     print "<refmeta>\n";
  752.     print " <refentrytitle><phrase id=\"$id\">enum ".$args{'enum'}."</phrase></refentrytitle>\n";
  753.     print " <manvolnum>9</manvolnum>\n";
  754.     print "</refmeta>\n";
  755.     print "<refnamediv>\n";
  756.     print " <refname>enum ".$args{'enum'}."</refname>\n";
  757.     print " <refpurpose>\n";
  758.     print "  ";
  759.     output_highlight ($args{'purpose'});
  760.     print " </refpurpose>\n";
  761.     print "</refnamediv>\n";
  762.  
  763.     print "<refsynopsisdiv>\n";
  764.     print " <title>Synopsis</title>\n";
  765.     print "  <programlisting>\n";
  766.     print "enum ".$args{'enum'}." {\n";
  767.     $count = 0;
  768.     foreach $parameter (@{$args{'parameterlist'}}) {
  769.         print "  $parameter";
  770.         if ($count != $#{$args{'parameterlist'}}) {
  771.         $count++;
  772.         print ",";
  773.         }
  774.     print "\n";
  775.     }
  776.     print "};";
  777.     print "  </programlisting>\n";
  778.     print "</refsynopsisdiv>\n";
  779.  
  780.     print "<refsect1>\n";
  781.     print " <title>Constants</title>\n";
  782.     print "  <variablelist>\n";
  783.     foreach $parameter (@{$args{'parameterlist'}}) {
  784.       my $parameter_name = $parameter;
  785.       $parameter_name =~ s/\[.*//;
  786.  
  787.       print "    <varlistentry>";
  788.       print "      <term>$parameter</term>\n";
  789.       print "      <listitem><para>\n";
  790.       output_highlight($args{'parameterdescs'}{$parameter_name});
  791.       print "      </para></listitem>\n";
  792.       print "    </varlistentry>\n";
  793.     }
  794.     print "  </variablelist>\n";
  795.     print "</refsect1>\n";
  796.  
  797.     output_section_xml(@_);
  798.  
  799.     print "</refentry>\n\n";
  800. }
  801.  
  802. # output typedef in XML DocBook
  803. sub output_typedef_xml(%) {
  804.     my %args = %{$_[0]};
  805.     my ($parameter, $section);
  806.     my $id;
  807.  
  808.     $id = "API-typedef-".$args{'typedef'};
  809.     $id =~ s/[^A-Za-z0-9]/-/g;
  810.  
  811.     print "<refentry>\n";
  812.     print "<refentryinfo>\n";
  813.     print " <title>LINUX</title>\n";
  814.     print " <productname>Kernel Hackers Manual</productname>\n";
  815.     print " <date>$man_date</date>\n";
  816.     print "</refentryinfo>\n";
  817.     print "<refmeta>\n";
  818.     print " <refentrytitle><phrase id=\"$id\">typedef ".$args{'typedef'}."</phrase></refentrytitle>\n";
  819.     print " <manvolnum>9</manvolnum>\n";
  820.     print "</refmeta>\n";
  821.     print "<refnamediv>\n";
  822.     print " <refname>typedef ".$args{'typedef'}."</refname>\n";
  823.     print " <refpurpose>\n";
  824.     print "  ";
  825.     output_highlight ($args{'purpose'});
  826.     print " </refpurpose>\n";
  827.     print "</refnamediv>\n";
  828.  
  829.     print "<refsynopsisdiv>\n";
  830.     print " <title>Synopsis</title>\n";
  831.     print "  <synopsis>typedef ".$args{'typedef'}.";</synopsis>\n";
  832.     print "</refsynopsisdiv>\n";
  833.  
  834.     output_section_xml(@_);
  835.  
  836.     print "</refentry>\n\n";
  837. }
  838.  
  839. # output in XML DocBook
  840. sub output_intro_xml(%) {
  841.     my %args = %{$_[0]};
  842.     my ($parameter, $section);
  843.     my $count;
  844.  
  845.     my $id = $args{'module'};
  846.     $id =~ s/[^A-Za-z0-9]/-/g;
  847.  
  848.     # print out each section
  849.     $lineprefix="   ";
  850.     foreach $section (@{$args{'sectionlist'}}) {
  851.     print "<refsect1>\n <title>$section</title>\n <para>\n";
  852.     if ($section =~ m/EXAMPLE/i) {
  853.         print "<example><para>\n";
  854.     }
  855.     output_highlight($args{'sections'}{$section});
  856.     if ($section =~ m/EXAMPLE/i) {
  857.         print "</para></example>\n";
  858.     }
  859.     print " </para>\n</refsect1>\n";
  860.     }
  861.  
  862.     print "\n\n";
  863. }
  864.  
  865. # output in XML DocBook
  866. sub output_function_gnome {
  867.     my %args = %{$_[0]};
  868.     my ($parameter, $section);
  869.     my $count;
  870.     my $id;
  871.  
  872.     $id = $args{'module'}."-".$args{'function'};
  873.     $id =~ s/[^A-Za-z0-9]/-/g;
  874.  
  875.     print "<sect2>\n";
  876.     print " <title id=\"$id\">".$args{'function'}."</title>\n";
  877.  
  878.     print "  <funcsynopsis>\n";
  879.     print "   <funcdef>".$args{'functiontype'}." ";
  880.     print "<function>".$args{'function'}." ";
  881.     print "</function></funcdef>\n";
  882.  
  883.     $count = 0;
  884.     if ($#{$args{'parameterlist'}} >= 0) {
  885.     foreach $parameter (@{$args{'parameterlist'}}) {
  886.         $type = $args{'parametertypes'}{$parameter};
  887.         if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
  888.         # pointer-to-function
  889.         print "   <paramdef>$1 <parameter>$parameter</parameter>)\n";
  890.         print "     <funcparams>$2</funcparams></paramdef>\n";
  891.         } else {
  892.         print "   <paramdef>".$type;
  893.         print " <parameter>$parameter</parameter></paramdef>\n";
  894.         }
  895.     }
  896.     } else {
  897.     print "  <void>\n";
  898.     }
  899.     print "  </funcsynopsis>\n";
  900.     if ($#{$args{'parameterlist'}} >= 0) {
  901.     print " <informaltable pgwide=\"1\" frame=\"none\" role=\"params\">\n";
  902.     print "<tgroup cols=\"2\">\n";
  903.     print "<colspec colwidth=\"2*\">\n";
  904.     print "<colspec colwidth=\"8*\">\n";
  905.     print "<tbody>\n";
  906.     foreach $parameter (@{$args{'parameterlist'}}) {
  907.         my $parameter_name = $parameter;
  908.         $parameter_name =~ s/\[.*//;
  909.  
  910.         print "  <row><entry align=\"right\"><parameter>$parameter</parameter></entry>\n";
  911.         print "   <entry>\n";
  912.         $lineprefix="     ";
  913.         output_highlight($args{'parameterdescs'}{$parameter_name});
  914.         print "    </entry></row>\n";
  915.     }
  916.     print " </tbody></tgroup></informaltable>\n";
  917.     } else {
  918.     print " <para>\n  None\n </para>\n";
  919.     }
  920.  
  921.     # print out each section
  922.     $lineprefix="   ";
  923.     foreach $section (@{$args{'sectionlist'}}) {
  924.     print "<simplesect>\n <title>$section</title>\n";
  925.     if ($section =~ m/EXAMPLE/i) {
  926.         print "<example><programlisting>\n";
  927.     } else {
  928.     }
  929.     print "<para>\n";
  930.     output_highlight($args{'sections'}{$section});
  931.     print "</para>\n";
  932.     if ($section =~ m/EXAMPLE/i) {
  933.         print "</programlisting></example>\n";
  934.     } else {
  935.     }
  936.     print " </simplesect>\n";
  937.     }
  938.  
  939.     print "</sect2>\n\n";
  940. }
  941.  
  942. ##
  943. # output function in man
  944. sub output_function_man(%) {
  945.     my %args = %{$_[0]};
  946.     my ($parameter, $section);
  947.     my $count;
  948.  
  949.     print ".TH \"$args{'function'}\" 9 \"$args{'function'}\" \"$man_date\" \"Kernel Hacker's Manual\" LINUX\n";
  950.  
  951.     print ".SH NAME\n";
  952.     print $args{'function'}." \\- ".$args{'purpose'}."\n";
  953.  
  954.     print ".SH SYNOPSIS\n";
  955.     print ".B \"".$args{'functiontype'}."\" ".$args{'function'}."\n";
  956.     $count = 0;
  957.     my $parenth = "(";
  958.     my $post = ",";
  959.     foreach my $parameter (@{$args{'parameterlist'}}) {
  960.     if ($count == $#{$args{'parameterlist'}}) {
  961.         $post = ");";
  962.     }
  963.     $type = $args{'parametertypes'}{$parameter};
  964.     if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
  965.         # pointer-to-function
  966.         print ".BI \"".$parenth.$1."\" ".$parameter." \") (".$2.")".$post."\"\n";
  967.     } else {
  968.         $type =~ s/([^\*])$/$1 /;
  969.         print ".BI \"".$parenth.$type."\" ".$parameter." \"".$post."\"\n";
  970.     }
  971.     $count++;
  972.     $parenth = "";
  973.     }
  974.  
  975.     print ".SH ARGUMENTS\n";
  976.     foreach $parameter (@{$args{'parameterlist'}}) {
  977.     my $parameter_name = $parameter;
  978.     $parameter_name =~ s/\[.*//;
  979.  
  980.     print ".IP \"".$parameter."\" 12\n";
  981.     output_highlight($args{'parameterdescs'}{$parameter_name});
  982.     }
  983.     foreach $section (@{$args{'sectionlist'}}) {
  984.     print ".SH \"", uc $section, "\"\n";
  985.     output_highlight($args{'sections'}{$section});
  986.     }
  987. }
  988.  
  989. ##
  990. # output enum in man
  991. sub output_enum_man(%) {
  992.     my %args = %{$_[0]};
  993.     my ($parameter, $section);
  994.     my $count;
  995.  
  996.     print ".TH \"$args{'module'}\" 9 \"enum $args{'enum'}\" \"$man_date\" \"API Manual\" LINUX\n";
  997.  
  998.     print ".SH NAME\n";
  999.     print "enum ".$args{'enum'}." \\- ".$args{'purpose'}."\n";
  1000.  
  1001.     print ".SH SYNOPSIS\n";
  1002.     print "enum ".$args{'enum'}." {\n";
  1003.     $count = 0;
  1004.     foreach my $parameter (@{$args{'parameterlist'}}) {
  1005.         print ".br\n.BI \"    $parameter\"\n";
  1006.     if ($count == $#{$args{'parameterlist'}}) {
  1007.         print "\n};\n";
  1008.         last;
  1009.     }
  1010.     else {
  1011.         print ", \n.br\n";
  1012.     }
  1013.     $count++;
  1014.     }
  1015.  
  1016.     print ".SH Constants\n";
  1017.     foreach $parameter (@{$args{'parameterlist'}}) {
  1018.     my $parameter_name = $parameter;
  1019.     $parameter_name =~ s/\[.*//;
  1020.  
  1021.     print ".IP \"".$parameter."\" 12\n";
  1022.     output_highlight($args{'parameterdescs'}{$parameter_name});
  1023.     }
  1024.     foreach $section (@{$args{'sectionlist'}}) {
  1025.     print ".SH \"$section\"\n";
  1026.     output_highlight($args{'sections'}{$section});
  1027.     }
  1028. }
  1029.  
  1030. ##
  1031. # output struct in man
  1032. sub output_struct_man(%) {
  1033.     my %args = %{$_[0]};
  1034.     my ($parameter, $section);
  1035.  
  1036.     print ".TH \"$args{'module'}\" 9 \"".$args{'type'}." ".$args{'struct'}."\" \"$man_date\" \"API Manual\" LINUX\n";
  1037.  
  1038.     print ".SH NAME\n";
  1039.     print $args{'type'}." ".$args{'struct'}." \\- ".$args{'purpose'}."\n";
  1040.  
  1041.     print ".SH SYNOPSIS\n";
  1042.     print $args{'type'}." ".$args{'struct'}." {\n.br\n";
  1043.  
  1044.     foreach my $parameter (@{$args{'parameterlist'}}) {
  1045.     if ($parameter =~ /^#/) {
  1046.         print ".BI \"$parameter\"\n.br\n";
  1047.         next;
  1048.     }
  1049.     my $parameter_name = $parameter;
  1050.     $parameter_name =~ s/\[.*//;
  1051.  
  1052.         ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
  1053.     $type = $args{'parametertypes'}{$parameter};
  1054.     if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
  1055.         # pointer-to-function
  1056.         print ".BI \"    ".$1."\" ".$parameter." \") (".$2.")"."\"\n;\n";
  1057.     } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
  1058.         print ".BI \"    ".$1."\" ".$parameter.$2." \""."\"\n;\n";
  1059.     } else {
  1060.         $type =~ s/([^\*])$/$1 /;
  1061.         print ".BI \"    ".$type."\" ".$parameter." \""."\"\n;\n";
  1062.     }
  1063.     print "\n.br\n";
  1064.     }
  1065.     print "};\n.br\n";
  1066.  
  1067.     print ".SH Arguments\n";
  1068.     foreach $parameter (@{$args{'parameterlist'}}) {
  1069.     ($parameter =~ /^#/) && next;
  1070.  
  1071.     my $parameter_name = $parameter;
  1072.     $parameter_name =~ s/\[.*//;
  1073.  
  1074.         ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
  1075.     print ".IP \"".$parameter."\" 12\n";
  1076.     output_highlight($args{'parameterdescs'}{$parameter_name});
  1077.     }
  1078.     foreach $section (@{$args{'sectionlist'}}) {
  1079.     print ".SH \"$section\"\n";
  1080.     output_highlight($args{'sections'}{$section});
  1081.     }
  1082. }
  1083.  
  1084. ##
  1085. # output typedef in man
  1086. sub output_typedef_man(%) {
  1087.     my %args = %{$_[0]};
  1088.     my ($parameter, $section);
  1089.  
  1090.     print ".TH \"$args{'module'}\" 9 \"$args{'typedef'}\" \"$man_date\" \"API Manual\" LINUX\n";
  1091.  
  1092.     print ".SH NAME\n";
  1093.     print "typedef ".$args{'typedef'}." \\- ".$args{'purpose'}."\n";
  1094.  
  1095.     foreach $section (@{$args{'sectionlist'}}) {
  1096.     print ".SH \"$section\"\n";
  1097.     output_highlight($args{'sections'}{$section});
  1098.     }
  1099. }
  1100.  
  1101. sub output_intro_man(%) {
  1102.     my %args = %{$_[0]};
  1103.     my ($parameter, $section);
  1104.     my $count;
  1105.  
  1106.     print ".TH \"$args{'module'}\" 9 \"$args{'module'}\" \"$man_date\" \"API Manual\" LINUX\n";
  1107.  
  1108.     foreach $section (@{$args{'sectionlist'}}) {
  1109.     print ".SH \"$section\"\n";
  1110.     output_highlight($args{'sections'}{$section});
  1111.     }
  1112. }
  1113.  
  1114. ##
  1115. # output in text
  1116. sub output_function_text(%) {
  1117.     my %args = %{$_[0]};
  1118.     my ($parameter, $section);
  1119.  
  1120.     print "Function:\n\n";
  1121.     my $start=$args{'functiontype'}." ".$args{'function'}." (";
  1122.     print $start;
  1123.     my $count = 0;
  1124.     foreach my $parameter (@{$args{'parameterlist'}}) {
  1125.     $type = $args{'parametertypes'}{$parameter};
  1126.     if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
  1127.         # pointer-to-function
  1128.         print $1.$parameter.") (".$2;
  1129.     } else {
  1130.         print $type." ".$parameter;
  1131.     }
  1132.     if ($count != $#{$args{'parameterlist'}}) {
  1133.         $count++;
  1134.         print ",\n";
  1135.         print " " x length($start);
  1136.     } else {
  1137.         print ");\n\n";
  1138.     }
  1139.     }
  1140.  
  1141.     print "Arguments:\n\n";
  1142.     foreach $parameter (@{$args{'parameterlist'}}) {
  1143.     my $parameter_name = $parameter;
  1144.     $parameter_name =~ s/\[.*//;
  1145.  
  1146.     print $parameter."\n\t".$args{'parameterdescs'}{$parameter_name}."\n";
  1147.     }
  1148.     output_section_text(@_);
  1149. }
  1150.  
  1151. #output sections in text
  1152. sub output_section_text(%) {
  1153.     my %args = %{$_[0]};
  1154.     my $section;
  1155.  
  1156.     print "\n";
  1157.     foreach $section (@{$args{'sectionlist'}}) {
  1158.     print "$section:\n\n";
  1159.     output_highlight($args{'sections'}{$section});
  1160.     }
  1161.     print "\n\n";
  1162. }
  1163.  
  1164. # output enum in text
  1165. sub output_enum_text(%) {
  1166.     my %args = %{$_[0]};
  1167.     my ($parameter);
  1168.     my $count;
  1169.     print "Enum:\n\n";
  1170.  
  1171.     print "enum ".$args{'enum'}." {\n";
  1172.     $count = 0;
  1173.     foreach $parameter (@{$args{'parameterlist'}}) {
  1174.         print "\t$parameter";
  1175.     if ($count != $#{$args{'parameterlist'}}) {
  1176.         $count++;
  1177.         print ",";
  1178.     }
  1179.     print "\n";
  1180.     }
  1181.     print "};\n\n";
  1182.  
  1183.     print "Constants:\n\n";
  1184.     foreach $parameter (@{$args{'parameterlist'}}) {
  1185.     print "$parameter\n\t";
  1186.     print $args{'parameterdescs'}{$parameter}."\n";
  1187.     }
  1188.  
  1189.     output_section_text(@_);
  1190. }
  1191.  
  1192. # output typedef in text
  1193. sub output_typedef_text(%) {
  1194.     my %args = %{$_[0]};
  1195.     my ($parameter);
  1196.     my $count;
  1197.     print "Typedef:\n\n";
  1198.  
  1199.     print "typedef ".$args{'typedef'}."\n";
  1200.     output_section_text(@_);
  1201. }
  1202.  
  1203. # output struct as text
  1204. sub output_struct_text(%) {
  1205.     my %args = %{$_[0]};
  1206.     my ($parameter);
  1207.  
  1208.     print $args{'type'}." ".$args{'struct'}.":\n\n";
  1209.     print $args{'type'}." ".$args{'struct'}." {\n";
  1210.     foreach $parameter (@{$args{'parameterlist'}}) {
  1211.     if ($parameter =~ /^#/) {
  1212.         print "$parameter\n";
  1213.         next;
  1214.     }
  1215.  
  1216.     my $parameter_name = $parameter;
  1217.     $parameter_name =~ s/\[.*//;
  1218.  
  1219.         ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
  1220.     $type = $args{'parametertypes'}{$parameter};
  1221.     if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
  1222.         # pointer-to-function
  1223.         print "\t$1 $parameter) ($2);\n";
  1224.     } elsif ($type =~ m/^(.*?)\s*(:.*)/) {
  1225.         print "\t$1 $parameter$2;\n";
  1226.     } else {
  1227.         print "\t".$type." ".$parameter.";\n";
  1228.     }
  1229.     }
  1230.     print "};\n\n";
  1231.  
  1232.     print "Members:\n\n";
  1233.     foreach $parameter (@{$args{'parameterlist'}}) {
  1234.     ($parameter =~ /^#/) && next;
  1235.  
  1236.     my $parameter_name = $parameter;
  1237.     $parameter_name =~ s/\[.*//;
  1238.  
  1239.         ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
  1240.     print "$parameter\n\t";
  1241.     print $args{'parameterdescs'}{$parameter_name}."\n";
  1242.     }
  1243.     print "\n";
  1244.     output_section_text(@_);
  1245. }
  1246.  
  1247. sub output_intro_text(%) {
  1248.     my %args = %{$_[0]};
  1249.     my ($parameter, $section);
  1250.  
  1251.     foreach $section (@{$args{'sectionlist'}}) {
  1252.     print " $section:\n";
  1253.     print "    -> ";
  1254.     output_highlight($args{'sections'}{$section});
  1255.     }
  1256. }
  1257.  
  1258. ##
  1259. # generic output function for typedefs
  1260. sub output_declaration {
  1261.     no strict 'refs';
  1262.     my $name = shift;
  1263.     my $functype = shift;
  1264.     my $func = "output_${functype}_$output_mode";
  1265.     if (($function_only==0) ||
  1266.     ( $function_only == 1 && defined($function_table{$name})) ||
  1267.     ( $function_only == 2 && !defined($function_table{$name})))
  1268.     {
  1269.         &$func(@_);
  1270.     $section_counter++;
  1271.     }
  1272. }
  1273.  
  1274. ##
  1275. # generic output function - calls the right one based
  1276. # on current output mode.
  1277. sub output_intro {
  1278.     no strict 'refs';
  1279.     my $func = "output_intro_".$output_mode;
  1280.     &$func(@_);
  1281.     $section_counter++;
  1282. }
  1283.  
  1284. ##
  1285. # takes a declaration (struct, union, enum, typedef) and
  1286. # invokes the right handler. NOT called for functions.
  1287. sub dump_declaration($$) {
  1288.     no strict 'refs';
  1289.     my ($prototype, $file) = @_;
  1290.     my $func = "dump_".$decl_type;
  1291.     &$func(@_);
  1292. }
  1293.  
  1294. sub dump_union($$) {
  1295.     dump_struct(@_);
  1296. }
  1297.  
  1298. sub dump_struct($$) {
  1299.     my $x = shift;
  1300.     my $file = shift;
  1301.  
  1302.     if ($x =~/(struct|union)\s+(\w+)\s*{(.*)}/) {
  1303.         $declaration_name = $2;
  1304.         my $members = $3;
  1305.  
  1306.     # ignore embedded structs or unions
  1307.     $members =~ s/{.*?}//g;
  1308.  
  1309.     # ignore members marked private:
  1310.     $members =~ s/\/\*.*?private:.*?public:.*?\*\///gos;
  1311.     $members =~ s/\/\*.*?private:.*//gos;
  1312.     # strip comments:
  1313.     $members =~ s/\/\*.*?\*\///gos;
  1314.  
  1315.     create_parameterlist($members, ';', $file);
  1316.  
  1317.     output_declaration($declaration_name,
  1318.                'struct',
  1319.                {'struct' => $declaration_name,
  1320.                 'module' => $modulename,
  1321.                 'parameterlist' => \@parameterlist,
  1322.                 'parameterdescs' => \%parameterdescs,
  1323.                 'parametertypes' => \%parametertypes,
  1324.                 'sectionlist' => \@sectionlist,
  1325.                 'sections' => \%sections,
  1326.                 'purpose' => $declaration_purpose,
  1327.                 'type' => $decl_type
  1328.                });
  1329.     }
  1330.     else {
  1331.         print STDERR "Error(${file}:$.): Cannot parse struct or union!\n";
  1332.     ++$errors;
  1333.     }
  1334. }
  1335.  
  1336. sub dump_enum($$) {
  1337.     my $x = shift;
  1338.     my $file = shift;
  1339.  
  1340.     $x =~ s@/\*.*?\*/@@gos;    # strip comments.
  1341.     if ($x =~ /enum\s+(\w+)\s*{(.*)}/) {
  1342.         $declaration_name = $1;
  1343.         my $members = $2;
  1344.  
  1345.     foreach my $arg (split ',', $members) {
  1346.         $arg =~ s/^\s*(\w+).*/$1/;
  1347.         push @parameterlist, $arg;
  1348.         if (!$parameterdescs{$arg}) {
  1349.             $parameterdescs{$arg} = $undescribed;
  1350.             print STDERR "Warning(${file}:$.): Enum value '$arg' ".
  1351.             "not described in enum '$declaration_name'\n";
  1352.         }
  1353.  
  1354.     }
  1355.  
  1356.     output_declaration($declaration_name,
  1357.                'enum',
  1358.                {'enum' => $declaration_name,
  1359.                 'module' => $modulename,
  1360.                 'parameterlist' => \@parameterlist,
  1361.                 'parameterdescs' => \%parameterdescs,
  1362.                 'sectionlist' => \@sectionlist,
  1363.                 'sections' => \%sections,
  1364.                 'purpose' => $declaration_purpose
  1365.                });
  1366.     }
  1367.     else {
  1368.         print STDERR "Error(${file}:$.): Cannot parse enum!\n";
  1369.     ++$errors;
  1370.     }
  1371. }
  1372.  
  1373. sub dump_typedef($$) {
  1374.     my $x = shift;
  1375.     my $file = shift;
  1376.  
  1377.     $x =~ s@/\*.*?\*/@@gos;    # strip comments.
  1378.     while (($x =~ /\(*.\)\s*;$/) || ($x =~ /\[*.\]\s*;$/)) {
  1379.         $x =~ s/\(*.\)\s*;$/;/;
  1380.     $x =~ s/\[*.\]\s*;$/;/;
  1381.     }
  1382.  
  1383.     if ($x =~ /typedef.*\s+(\w+)\s*;/) {
  1384.         $declaration_name = $1;
  1385.  
  1386.     output_declaration($declaration_name,
  1387.                'typedef',
  1388.                {'typedef' => $declaration_name,
  1389.                 'module' => $modulename,
  1390.                 'sectionlist' => \@sectionlist,
  1391.                 'sections' => \%sections,
  1392.                 'purpose' => $declaration_purpose
  1393.                });
  1394.     }
  1395.     else {
  1396.         print STDERR "Error(${file}:$.): Cannot parse typedef!\n";
  1397.     ++$errors;
  1398.     }
  1399. }
  1400.  
  1401. sub create_parameterlist($$$) {
  1402.     my $args = shift;
  1403.     my $splitter = shift;
  1404.     my $file = shift;
  1405.     my $type;
  1406.     my $param;
  1407.  
  1408.     # temporarily replace commas inside function pointer definition
  1409.     while ($args =~ /(\([^\),]+),/) {
  1410.         $args =~ s/(\([^\),]+),/$1#/g;
  1411.     }
  1412.  
  1413.     foreach my $arg (split($splitter, $args)) {
  1414.     # strip comments
  1415.     $arg =~ s/\/\*.*\*\///;
  1416.         # strip leading/trailing spaces
  1417.         $arg =~ s/^\s*//;
  1418.     $arg =~ s/\s*$//;
  1419.     $arg =~ s/\s+/ /;
  1420.  
  1421.     if ($arg =~ /^#/) {
  1422.         # Treat preprocessor directive as a typeless variable just to fill
  1423.         # corresponding data structures "correctly". Catch it later in
  1424.         # output_* subs.
  1425.         push_parameter($arg, "", $file);
  1426.     } elsif ($arg =~ m/\(/) {
  1427.         # pointer-to-function
  1428.         $arg =~ tr/#/,/;
  1429.         $arg =~ m/[^\(]+\(\*([^\)]+)\)/;
  1430.         $param = $1;
  1431.         $type = $arg;
  1432.         $type =~ s/([^\(]+\(\*)$param/$1/;
  1433.         push_parameter($param, $type, $file);
  1434.     } elsif ($arg) {
  1435.         $arg =~ s/\s*:\s*/:/g;
  1436.         $arg =~ s/\s*\[/\[/g;
  1437.  
  1438.         my @args = split('\s*,\s*', $arg);
  1439.         if ($args[0] =~ m/\*/) {
  1440.         $args[0] =~ s/(\*+)\s*/ $1/;
  1441.         }
  1442.         my @first_arg = split('\s+', shift @args);
  1443.         unshift(@args, pop @first_arg);
  1444.         $type = join " ", @first_arg;
  1445.  
  1446.         foreach $param (@args) {
  1447.         if ($param =~ m/^(\*+)\s*(.*)/) {
  1448.             push_parameter($2, "$type $1", $file);
  1449.         }
  1450.         elsif ($param =~ m/(.*?):(\d+)/) {
  1451.             push_parameter($1, "$type:$2", $file)
  1452.         }
  1453.         else {
  1454.             push_parameter($param, $type, $file);
  1455.         }
  1456.         }
  1457.     }
  1458.     }
  1459. }
  1460.  
  1461. sub push_parameter($$$) {
  1462.     my $param = shift;
  1463.     my $type = shift;
  1464.     my $file = shift;
  1465.  
  1466.     my $param_name = $param;
  1467.     $param_name =~ s/\[.*//;
  1468.  
  1469.     if ($type eq "" && $param =~ /\.\.\.$/)
  1470.     {
  1471.         $type="";
  1472.         $parameterdescs{$param} = "variable arguments";
  1473.     }
  1474.     elsif ($type eq "" && ($param eq "" or $param eq "void"))
  1475.     {
  1476.         $type="";
  1477.         $param="void";
  1478.         $parameterdescs{void} = "no arguments";
  1479.     }
  1480.     # warn if parameter has no description
  1481.     # (but ignore ones starting with # as these are no parameters
  1482.     # but inline preprocessor statements
  1483.     if (!defined $parameterdescs{$param_name} && $param_name !~ /^#/) {
  1484.  
  1485.         $parameterdescs{$param_name} = $undescribed;
  1486.  
  1487.         if (($type eq 'function') || ($type eq 'enum')) {
  1488.             print STDERR "Warning(${file}:$.): Function parameter ".
  1489.             "or member '$param' not " .
  1490.             "described in '$declaration_name'\n";
  1491.         }
  1492.         print STDERR "Warning(${file}:$.):".
  1493.                      " No description found for parameter '$param'\n";
  1494.         ++$warnings;
  1495.         }
  1496.  
  1497.     push @parameterlist, $param;
  1498.     $parametertypes{$param} = $type;
  1499. }
  1500.  
  1501. ##
  1502. # takes a function prototype and the name of the current file being
  1503. # processed and spits out all the details stored in the global
  1504. # arrays/hashes.
  1505. sub dump_function($$) {
  1506.     my $prototype = shift;
  1507.     my $file = shift;
  1508.  
  1509.     $prototype =~ s/^static +//;
  1510.     $prototype =~ s/^extern +//;
  1511.     $prototype =~ s/^fastcall +//;
  1512.     $prototype =~ s/^asmlinkage +//;
  1513.     $prototype =~ s/^inline +//;
  1514.     $prototype =~ s/^__inline__ +//;
  1515.     $prototype =~ s/^#define +//; #ak added
  1516.     $prototype =~ s/__attribute__ \(\([a-z,]*\)\)//;
  1517.  
  1518.     # Yes, this truly is vile.  We are looking for:
  1519.     # 1. Return type (may be nothing if we're looking at a macro)
  1520.     # 2. Function name
  1521.     # 3. Function parameters.
  1522.     #
  1523.     # All the while we have to watch out for function pointer parameters
  1524.     # (which IIRC is what the two sections are for), C types (these
  1525.     # regexps don't even start to express all the possibilities), and
  1526.     # so on.
  1527.     #
  1528.     # If you mess with these regexps, it's a good idea to check that
  1529.     # the following functions' documentation still comes out right:
  1530.     # - parport_register_device (function pointer parameters)
  1531.     # - atomic_set (macro)
  1532.     # - pci_match_device, __copy_to_user (long return type)
  1533.  
  1534.     if ($prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
  1535.     $prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
  1536.     $prototype =~ m/^(\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
  1537.     $prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
  1538.     $prototype =~ m/^(\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
  1539.     $prototype =~ m/^(\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
  1540.     $prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ ||
  1541.     $prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
  1542.     $prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
  1543.     $prototype =~ m/^(\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
  1544.     $prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
  1545.     $prototype =~ m/^(\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
  1546.     $prototype =~ m/^(\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
  1547.     $prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
  1548.     $prototype =~ m/^(\w+\s+\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ ||
  1549.     $prototype =~ m/^(\w+\s+\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/)  {
  1550.     $return_type = $1;
  1551.     $declaration_name = $2;
  1552.     my $args = $3;
  1553.  
  1554.     create_parameterlist($args, ',', $file);
  1555.     } else {
  1556.     print STDERR "Error(${file}:$.): cannot understand prototype: '$prototype'\n";
  1557.     ++$errors;
  1558.     return;
  1559.     }
  1560.  
  1561.     output_declaration($declaration_name,
  1562.                'function',
  1563.                {'function' => $declaration_name,
  1564.             'module' => $modulename,
  1565.             'functiontype' => $return_type,
  1566.             'parameterlist' => \@parameterlist,
  1567.             'parameterdescs' => \%parameterdescs,
  1568.             'parametertypes' => \%parametertypes,
  1569.             'sectionlist' => \@sectionlist,
  1570.             'sections' => \%sections,
  1571.             'purpose' => $declaration_purpose
  1572.                });
  1573. }
  1574.  
  1575. sub process_file($);
  1576.  
  1577. # Read the file that maps relative names to absolute names for
  1578. # separate source and object directories and for shadow trees.
  1579. if (open(SOURCE_MAP, "<.tmp_filelist.txt")) {
  1580.     my ($relname, $absname);
  1581.     while(<SOURCE_MAP>) {
  1582.         chop();
  1583.         ($relname, $absname) = (split())[0..1];
  1584.         $relname =~ s:^/+::;
  1585.         $source_map{$relname} = $absname;
  1586.     }
  1587.     close(SOURCE_MAP);
  1588. }
  1589.  
  1590. if ($filelist) {
  1591.     open(FLIST,"<$filelist") or die "Can't open file list $filelist";
  1592.     while(<FLIST>) {
  1593.         chop;
  1594.         process_file($_);
  1595.     }
  1596. }
  1597.  
  1598. foreach (@ARGV) {
  1599.     chomp;
  1600.     process_file($_);
  1601. }
  1602. if ($verbose && $errors) {
  1603.   print STDERR "$errors errors\n";
  1604. }
  1605. if ($verbose && $warnings) {
  1606.   print STDERR "$warnings warnings\n";
  1607. }
  1608.  
  1609. exit($errors);
  1610.  
  1611. sub reset_state {
  1612.     $function = "";
  1613.     %constants = ();
  1614.     %parameterdescs = ();
  1615.     %parametertypes = ();
  1616.     @parameterlist = ();
  1617.     %sections = ();
  1618.     @sectionlist = ();
  1619.     $prototype = "";
  1620.  
  1621.     $state = 0;
  1622. }
  1623.  
  1624. sub process_state3_function($$) {
  1625.     my $x = shift;
  1626.     my $file = shift;
  1627.  
  1628.     if ($x =~ m#\s*/\*\s+MACDOC\s*#io || ($x =~ /^#/ && $x !~ /^#define/)) {
  1629.     # do nothing
  1630.     }
  1631.     elsif ($x =~ /([^\{]*)/) {
  1632.         $prototype .= $1;
  1633.     }
  1634.     if (($x =~ /\{/) || ($x =~ /\#define/) || ($x =~ /;/)) {
  1635.         $prototype =~ s@/\*.*?\*/@@gos;    # strip comments.
  1636.     $prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
  1637.     $prototype =~ s@^\s+@@gos; # strip leading spaces
  1638.     dump_function($prototype,$file);
  1639.     reset_state();
  1640.     }
  1641. }
  1642.  
  1643. sub process_state3_type($$) {
  1644.     my $x = shift;
  1645.     my $file = shift;
  1646.  
  1647.     $x =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
  1648.     $x =~ s@^\s+@@gos; # strip leading spaces
  1649.     $x =~ s@\s+$@@gos; # strip trailing spaces
  1650.     if ($x =~ /^#/) {
  1651.     # To distinguish preprocessor directive from regular declaration later.
  1652.     $x .= ";";
  1653.     }
  1654.  
  1655.     while (1) {
  1656.         if ( $x =~ /([^{};]*)([{};])(.*)/ ) {
  1657.         $prototype .= $1 . $2;
  1658.         ($2 eq '{') && $brcount++;
  1659.         ($2 eq '}') && $brcount--;
  1660.         if (($2 eq ';') && ($brcount == 0)) {
  1661.             dump_declaration($prototype,$file);
  1662.         reset_state();
  1663.             last;
  1664.         }
  1665.         $x = $3;
  1666.         } else {
  1667.         $prototype .= $x;
  1668.         last;
  1669.     }
  1670.     }
  1671. }
  1672.  
  1673. # replace <, >, and &
  1674. sub xml_escape($) {
  1675.     my $text = shift;
  1676.     $text =~ s/\&/\\\\\\amp;/g;
  1677.     $text =~ s/\</\\\\\\lt;/g;
  1678.     $text =~ s/\>/\\\\\\gt;/g;
  1679.     return $text;
  1680. }
  1681.  
  1682. sub process_file($) {
  1683.     my $file;
  1684.     my $identifier;
  1685.     my $func;
  1686.     my $initial_section_counter = $section_counter;
  1687.  
  1688.     if (defined($ENV{'SRCTREE'})) {
  1689.     $file = "$ENV{'SRCTREE'}" . "/" . "@_";
  1690.     }
  1691.     else {
  1692.     $file = "@_";
  1693.     }
  1694.     if (defined($source_map{$file})) {
  1695.     $file = $source_map{$file};
  1696.     }
  1697.  
  1698.     if (!open(IN,"<$file")) {
  1699.     print STDERR "Error: Cannot open file $file\n";
  1700.     ++$errors;
  1701.     return;
  1702.     }
  1703.  
  1704.     $section_counter = 0;
  1705.     while (<IN>) {
  1706.     if ($state == 0) {
  1707.         if (/$doc_start/o) {
  1708.         $state = 1;        # next line is always the function name
  1709.         }
  1710.     } elsif ($state == 1) {    # this line is the function name (always)
  1711.         if (/$doc_block/o) {
  1712.         $state = 4;
  1713.         $contents = "";
  1714.         if ( $1 eq "" ) {
  1715.             $section = $section_intro;
  1716.         } else {
  1717.             $section = $1;
  1718.         }
  1719.             }
  1720.         elsif (/$doc_decl/o) {
  1721.         $identifier = $1;
  1722.         if (/\s*([\w\s]+?)\s*-/) {
  1723.             $identifier = $1;
  1724.         }
  1725.  
  1726.         $state = 2;
  1727.         if (/-(.*)/) {
  1728.             $declaration_purpose = xml_escape($1);
  1729.         } else {
  1730.             $declaration_purpose = "";
  1731.         }
  1732.         if ($identifier =~ m/^struct/) {
  1733.             $decl_type = 'struct';
  1734.         } elsif ($identifier =~ m/^union/) {
  1735.             $decl_type = 'union';
  1736.         } elsif ($identifier =~ m/^enum/) {
  1737.             $decl_type = 'enum';
  1738.         } elsif ($identifier =~ m/^typedef/) {
  1739.             $decl_type = 'typedef';
  1740.         } else {
  1741.             $decl_type = 'function';
  1742.         }
  1743.  
  1744.         if ($verbose) {
  1745.             print STDERR "Info(${file}:$.): Scanning doc for $identifier\n";
  1746.         }
  1747.         } else {
  1748.         print STDERR "Warning(${file}:$.): Cannot understand $_ on line $.",
  1749.         " - I thought it was a doc line\n";
  1750.         ++$warnings;
  1751.         $state = 0;
  1752.         }
  1753.     } elsif ($state == 2) {    # look for head: lines, and include content
  1754.         if (/$doc_sect/o) {
  1755.         $newsection = $1;
  1756.         $newcontents = $2;
  1757.  
  1758.         if ($contents ne "") {
  1759.             dump_section($section, xml_escape($contents));
  1760.             $section = $section_default;
  1761.         }
  1762.  
  1763.         $contents = $newcontents;
  1764.         if ($contents ne "") {
  1765.             $contents .= "\n";
  1766.         }
  1767.         $section = $newsection;
  1768.         } elsif (/$doc_end/) {
  1769.  
  1770.         if ($contents ne "") {
  1771.             dump_section($section, xml_escape($contents));
  1772.             $section = $section_default;
  1773.             $contents = "";
  1774.         }
  1775.  
  1776.         $prototype = "";
  1777.         $state = 3;
  1778.         $brcount = 0;
  1779. #        print STDERR "end of doc comment, looking for prototype\n";
  1780.         } elsif (/$doc_content/) {
  1781.         # miguel-style comment kludge, look for blank lines after
  1782.         # @parameter line to signify start of description
  1783.         if ($1 eq "" &&
  1784.             ($section =~ m/^@/ || $section eq $section_context)) {
  1785.             dump_section($section, xml_escape($contents));
  1786.             $section = $section_default;
  1787.             $contents = "";
  1788.         } else {
  1789.             $contents .= $1."\n";
  1790.         }
  1791.         } else {
  1792.         # i dont know - bad line?  ignore.
  1793.         print STDERR "Warning(${file}:$.): bad line: $_";
  1794.         ++$warnings;
  1795.         }
  1796.     } elsif ($state == 3) {    # scanning for function { (end of prototype)
  1797.         if ($decl_type eq 'function') {
  1798.             process_state3_function($_, $file);
  1799.         } else {
  1800.             process_state3_type($_, $file);
  1801.         }
  1802.     } elsif ($state == 4) {
  1803.         # Documentation block
  1804.             if (/$doc_block/) {
  1805.             dump_section($section, $contents);
  1806.             output_intro({'sectionlist' => \@sectionlist,
  1807.                       'sections' => \%sections });
  1808.             $contents = "";
  1809.             $function = "";
  1810.             %constants = ();
  1811.             %parameterdescs = ();
  1812.             %parametertypes = ();
  1813.             @parameterlist = ();
  1814.             %sections = ();
  1815.             @sectionlist = ();
  1816.             $prototype = "";
  1817.             if ( $1 eq "" ) {
  1818.                 $section = $section_intro;
  1819.             } else {
  1820.                 $section = $1;
  1821.             }
  1822.                 }
  1823.         elsif (/$doc_end/)
  1824.         {
  1825.             dump_section($section, $contents);
  1826.             output_intro({'sectionlist' => \@sectionlist,
  1827.                       'sections' => \%sections });
  1828.             $contents = "";
  1829.             $function = "";
  1830.             %constants = ();
  1831.             %parameterdescs = ();
  1832.             %parametertypes = ();
  1833.             @parameterlist = ();
  1834.             %sections = ();
  1835.             @sectionlist = ();
  1836.             $prototype = "";
  1837.             $state = 0;
  1838.         }
  1839.         elsif (/$doc_content/)
  1840.         {
  1841.             if ( $1 eq "" )
  1842.             {
  1843.                 $contents .= $blankline;
  1844.             }
  1845.             else
  1846.             {
  1847.                 $contents .= $1 . "\n";
  1848.             }
  1849.             }
  1850.           }
  1851.     }
  1852.     if ($initial_section_counter == $section_counter) {
  1853.     print STDERR "Warning(${file}): no structured comments found\n";
  1854.     if ($output_mode eq "xml") {
  1855.         # The template wants at least one RefEntry here; make one.
  1856.         print "<refentry>\n";
  1857.         print " <refnamediv>\n";
  1858.         print "  <refname>\n";
  1859.         print "   ${file}\n";
  1860.         print "  </refname>\n";
  1861.         print "  <refpurpose>\n";
  1862.         print "   Document generation inconsistency\n";
  1863.         print "  </refpurpose>\n";
  1864.         print " </refnamediv>\n";
  1865.         print " <refsect1>\n";
  1866.         print "  <title>\n";
  1867.         print "   Oops\n";
  1868.         print "  </title>\n";
  1869.         print "  <warning>\n";
  1870.         print "   <para>\n";
  1871.         print "    The template for this document tried to insert\n";
  1872.         print "    the structured comment from the file\n";
  1873.         print "    <filename>${file}</filename> at this point,\n";
  1874.         print "    but none was found.\n";
  1875.         print "    This dummy section is inserted to allow\n";
  1876.         print "    generation to continue.\n";
  1877.         print "   </para>\n";
  1878.         print "  </warning>\n";
  1879.         print " </refsect1>\n";
  1880.         print "</refentry>\n";
  1881.     }
  1882.     }
  1883. }
  1884.