kernel-doc
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:44k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. #!/usr/bin/perl -w
  2. use strict;
  3. ## Copyright (c) 1998 Michael Zucchi, All Rights Reserved        ##
  4. ## Copyright (C) 2000, 1  Tim Waugh <twaugh@redhat.com>          ##
  5. ## Copyright (C) 2001  Simon Huggins                             ##
  6. ##   ##
  7. ## #define enhancements by Armin Kuster <akuster@mvista.com>  ##
  8. ## Copyright (c) 2000 MontaVista Software, Inc.  ##
  9. ##   ##
  10. ## This software falls under the GNU General Public License.     ##
  11. ## Please read the COPYING file for more information             ##
  12. # w.o. 03-11-2000: added the '-filelist' option.
  13. # 18/01/2001 -  Cleanups
  14. #  Functions prototyped as foo(void) same as foo()
  15. #  Stop eval'ing where we don't need to.
  16. # -- huggie@earth.li
  17. # 27/06/2001 -  Allowed whitespace after initial "/**" and
  18. #               allowed comments before function declarations.
  19. # -- Christian Kreibich <ck@whoop.org>
  20. # Still to do:
  21. #  - add perldoc documentation
  22. #  - Look more closely at some of the scarier bits :)
  23. # 26/05/2001 -  Support for separate source and object trees.
  24. # Return error code.
  25. #  Keith Owens <kaos@ocs.com.au>
  26. # 23/09/2001 - Added support for typedefs, structs, enums and unions
  27. #              Support for Context section; can be terminated using empty line
  28. #              Small fixes (like spaces vs. s in regex)
  29. # -- Tim Jansen <tim@tjansen.de>
  30. #
  31. # This will read a 'c' file and scan for embedded comments in the
  32. # style of gnome comments (+minor extensions - see below).
  33. #
  34. # Note: This only supports 'c'.
  35. # usage:
  36. # kerneldoc [ -docbook | -html | -text | -man ]
  37. #           [ -function funcname [ -function funcname ...] ] c file(s)s > outputfile
  38. # or
  39. #           [ -nofunction funcname [ -function funcname ...] ] c file(s)s > outputfile
  40. #
  41. #  Set output format using one of -docbook -html -text or -man.  Default is man.
  42. #
  43. #  -function funcname
  44. # If set, then only generate documentation for the given function(s).  All
  45. # other functions are ignored.
  46. #
  47. #  -nofunction funcname
  48. # If set, then only generate documentation for the other function(s).  All
  49. # other functions are ignored. Cannot be used with -function together
  50. # (yes thats a bug - perl hackers can fix it 8))
  51. #
  52. #  c files - list of 'c' files to process
  53. #
  54. #  All output goes to stdout, with errors to stderr.
  55. #
  56. # format of comments.
  57. # In the following table, (...)? signifies optional structure.
  58. #                         (...)* signifies 0 or more structure elements
  59. # /**
  60. #  * function_name(:)? (- short description)?
  61. # (* @parameterx: (description of parameter x)?)*
  62. # (* a blank line)?
  63. #  * (Description:)? (Description of function)?
  64. #  * (section header: (section description)? )*
  65. #  (*)?*/
  66. #
  67. # So .. the trivial example would be:
  68. #
  69. # /**
  70. #  * my_function
  71. #  **/
  72. #
  73. # If the Description: header tag is ommitted, then there must be a blank line
  74. # after the last parameter specification.
  75. # e.g.
  76. # /**
  77. #  * my_function - does my stuff
  78. #  * @my_arg: its mine damnit
  79. #  *
  80. #  * Does my stuff explained. 
  81. #  */
  82. #
  83. #  or, could also use:
  84. # /**
  85. #  * my_function - does my stuff
  86. #  * @my_arg: its mine damnit
  87. #  * Description: Does my stuff explained. 
  88. #  */
  89. # etc.
  90. #
  91. # Beside functions you can also write documentation for structs, unions, 
  92. # enums and typedefs. Instead of the function name you must write the name 
  93. # of the declaration;  the struct/union/enum/typedef must always precede 
  94. # the name. Nesting of declarations is not supported. 
  95. # Use the argument mechanism to document members or constants. In 
  96. # structs and unions you must declare one member per declaration 
  97. # (comma-separated members are not allowed -  the parser does not support 
  98. # this).
  99. # e.g.
  100. # /**
  101. #  * struct my_struct - short description
  102. #  * @a: first member
  103. #  * @b: second member
  104. #  * 
  105. #  * Longer description
  106. #  */
  107. # struct my_struct {
  108. #     int a;
  109. #     int b;
  110. # };
  111. #
  112. # All descriptions can be multiline, except the short function description.
  113. # You can also add additional sections. When documenting kernel functions you 
  114. # should document the "Context:" of the function, e.g. whether the functions 
  115. # can be called form interrupts. Unlike other sections you can end it with an
  116. # empty line. 
  117. # Example-sections should contain the string EXAMPLE so that they are marked 
  118. # appropriately in DocBook.
  119. #
  120. # Example:
  121. # /**
  122. #  * user_function - function that can only be called in user context
  123. #  * @a: some argument
  124. #  * Context: !in_interrupt()
  125. #  * 
  126. #  * Some description
  127. #  * Example:
  128. #  *    user_function(22);
  129. #  */
  130. # ...
  131. #
  132. #
  133. # All descriptive text is further processed, scanning for the following special
  134. # patterns, which are highlighted appropriately.
  135. #
  136. # 'funcname()' - function
  137. # '$ENVVAR' - environmental variable
  138. # '&struct_name' - name of a structure (up to two words including 'struct')
  139. # '@parameter' - name of a parameter
  140. # '%CONST' - name of a constant.
  141. my $errors = 0;
  142. # match expressions used to find embedded type information
  143. my $type_constant = '%([-_w]+)';
  144. my $type_func = '(w+)()';
  145. my $type_param = '@(w+)';
  146. my $type_struct = '&((structs*)?[_w]+)';
  147. my $type_env = '($w+)';
  148. # Output conversion substitutions.
  149. #  One for each output format
  150. # these work fairly well
  151. my %highlights_html = ( $type_constant, "<i>$1</i>",
  152. $type_func, "<b>$1</b>",
  153. $type_struct, "<i>$1</i>",
  154. $type_param, "<tt><b>$1</b></tt>" );
  155. my $blankline_html = "<p>";
  156. # sgml, docbook format
  157. my %highlights_sgml = ( "([^=])\"([^\"<]+)\"", "$1<quote>$2</quote>",
  158. $type_constant, "<constant>$1</constant>",
  159. $type_func, "<function>$1</function>",
  160. $type_struct, "<structname>$1</structname>",
  161. $type_env, "<envar>$1</envar>",
  162. $type_param, "<parameter>$1</parameter>" );
  163. my $blankline_sgml = "</para><para>n";
  164. # gnome, docbook format
  165. my %highlights_gnome = ( $type_constant, "<replaceable class="option">$1</replaceable>",
  166.  $type_func, "<function>$1</function>",
  167.  $type_struct, "<structname>$1</structname>",
  168.  $type_env, "<envar>$1</envar>",
  169.  $type_param, "<parameter>$1</parameter>" );
  170. my $blankline_gnome = "</para><para>n";
  171. # these are pretty rough
  172. my %highlights_man = ( $type_constant, "$1",
  173.        $type_func, "\\fB$1\\fP",
  174.        $type_struct, "\\fI$1\\fP",
  175.        $type_param, "\\fI$1\\fP" );
  176. my $blankline_man = "";
  177. # text-mode
  178. my %highlights_text = ( $type_constant, "$1",
  179. $type_func, "$1",
  180. $type_struct, "$1",
  181. $type_param, "$1" );
  182. my $blankline_text = "";
  183. sub usage {
  184.     print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man ]n";
  185.     print "         [ -function funcname [ -function funcname ...] ]n";
  186.     print "         [ -nofunction funcname [ -nofunction funcname ...] ]n";
  187.     print "         c source file(s) > outputfilen";
  188.     exit 1;
  189. }
  190. # read arguments
  191. if ($#ARGV==-1) {
  192.     usage();
  193. }
  194. my $verbose = 0;
  195. my $output_mode = "man";
  196. my %highlights = %highlights_man;
  197. my $blankline = $blankline_man;
  198. my $modulename = "Kernel API";
  199. my $function_only = 0;
  200. my $man_date = ('January', 'February', 'March', 'April', 'May', 'June', 
  201. 'July', 'August', 'September', 'October', 
  202. 'November', 'December')[(localtime)[4]] . 
  203.   " " . ((localtime)[5]+1900);
  204. # Essentially these are globals
  205. # They probably want to be tidied up made more localised or summat.
  206. # CAVEAT EMPTOR!  Some of the others I localised may not want to be which
  207. # could cause "use of undefined value" or other bugs.
  208. my ($function, %function_table,%parametertypes,$declaration_purpose);
  209. my ($type,$file,$declaration_name,$return_type);
  210. my ($newsection,$newcontents,$prototype,$filelist, $brcount, %source_map);
  211. my $lineprefix="";
  212. # states
  213. # 0 - normal code
  214. # 1 - looking for function name
  215. # 2 - scanning field start.
  216. # 3 - scanning prototype.
  217. # 4 - documentation block
  218. my $state;
  219. #declaration types: can be
  220. # 'function', 'struct', 'union', 'enum', 'typedef'
  221. my $decl_type;
  222. my $doc_special = "@%$&";
  223. my $doc_start = '^/**s*$'; # Allow whitespace at end of comment start.
  224. my $doc_end = '*/';
  225. my $doc_com = 's**s*';
  226. my $doc_decl = $doc_com.'(w+)';
  227. my $doc_sect = $doc_com.'(['.$doc_special.']?[w ]+):(.*)';
  228. my $doc_content = $doc_com.'(.*)';
  229. my $doc_block = $doc_com.'DOC:s*(.*)?';
  230. my %constants;
  231. my %parameterdescs;
  232. my @parameterlist;
  233. my %sections;
  234. my @sectionlist;
  235. my $contents = "";
  236. my $section_default = "Description"; # default section
  237. my $section_intro = "Introduction";
  238. my $section = $section_default;
  239. my $section_context = "Context";
  240. my $undescribed = "-- undescribed --";
  241. reset_state();
  242. while ($ARGV[0] =~ m/^-(.*)/) {
  243.     my $cmd = shift @ARGV;
  244.     if ($cmd eq "-html") {
  245. $output_mode = "html";
  246. %highlights = %highlights_html;
  247. $blankline = $blankline_html;
  248.     } elsif ($cmd eq "-man") {
  249. $output_mode = "man";
  250. %highlights = %highlights_man;
  251. $blankline = $blankline_man;
  252.     } elsif ($cmd eq "-text") {
  253. $output_mode = "text";
  254. %highlights = %highlights_text;
  255. $blankline = $blankline_text;
  256.     } elsif ($cmd eq "-docbook") {
  257. $output_mode = "sgml";
  258. %highlights = %highlights_sgml;
  259. $blankline = $blankline_sgml;
  260.     } elsif ($cmd eq "-gnome") {
  261. $output_mode = "gnome";
  262. %highlights = %highlights_gnome;
  263. $blankline = $blankline_gnome;
  264.     } elsif ($cmd eq "-module") { # not needed for sgml, inherits from calling document
  265. $modulename = shift @ARGV;
  266.     } elsif ($cmd eq "-function") { # to only output specific functions
  267. $function_only = 1;
  268. $function = shift @ARGV;
  269. $function_table{$function} = 1;
  270.     } elsif ($cmd eq "-nofunction") { # to only output specific functions
  271. $function_only = 2;
  272. $function = shift @ARGV;
  273. $function_table{$function} = 1;
  274.     } elsif ($cmd eq "-v") {
  275. $verbose = 1;
  276.     } elsif (($cmd eq "-h") || ($cmd eq "--help")) {
  277. usage();
  278.     } elsif ($cmd eq '-filelist') {
  279.     $filelist = shift @ARGV;
  280.     }
  281. }
  282. # generate a sequence of code that will splice in highlighting information
  283. # using the s// operator.
  284. my $dohighlight = "";
  285. foreach my $pattern (keys %highlights) {
  286. #    print "scanning pattern $pattern ($highlights{$pattern})n";
  287.     $dohighlight .=  "$contents =~ s:$pattern:$highlights{$pattern}:gs;n";
  288. }
  289. ##
  290. # dumps section contents to arrays/hashes intended for that purpose.
  291. #
  292. sub dump_section {
  293.     my $name = shift;
  294.     my $contents = join "n", @_;
  295.     if ($name =~ m/$type_constant/) {
  296. $name = $1;
  297. # print STDERR "constant section '$1' = '$contents'n";
  298. $constants{$name} = $contents;
  299.     } elsif ($name =~ m/$type_param/) {
  300. # print STDERR "parameter def '$1' = '$contents'n";
  301. $name = $1;
  302. $parameterdescs{$name} = $contents;
  303.     } else {
  304. # print STDERR "other section '$name' = '$contents'n";
  305. $sections{$name} = $contents;
  306. push @sectionlist, $name;
  307.     }
  308. }
  309. ##
  310. # output function
  311. #
  312. # parameterdescs, a hash.
  313. #  function => "function name"
  314. #  parameterlist => @list of parameters
  315. #  parameterdescs => %parameter descriptions
  316. #  sectionlist => @list of sections
  317. #  sections => %descriont descriptions
  318. #  
  319. sub output_highlight {
  320.     my $contents = join "n",@_;
  321.     my $line;
  322. #   DEBUG
  323. #   if (!defined $contents) {
  324. # use Carp;
  325. # confess "output_highlight got called with no args?n";
  326. #   }
  327.     eval $dohighlight;
  328.     die $@ if $@;
  329.     foreach $line (split "n", $contents) {
  330.       if ($line eq ""){
  331.     print $lineprefix, $blankline;
  332. } else {
  333.             $line =~ s/\\\/&/g;
  334.     print $lineprefix, $line;
  335. }
  336. print "n";
  337.     }
  338. }
  339. #output sections in html
  340. sub output_section_html(%) {
  341.     my %args = %{$_[0]};
  342.     my $section;
  343.     foreach $section (@{$args{'sectionlist'}}) {
  344. print "<h3>$section</h3>n";
  345. print "<blockquote>n";
  346. output_highlight($args{'sections'}{$section});
  347. print "</blockquote>n";
  348.     }  
  349. }
  350. # output enum in html
  351. sub output_enum_html(%) {
  352.     my %args = %{$_[0]};
  353.     my ($parameter);
  354.     my $count;
  355.     print "<h2>enum ".$args{'enum'}."</h2>n";
  356.     print "<b>enum ".$args{'enum'}."</b> {<br>n";
  357.     $count = 0;
  358.     foreach $parameter (@{$args{'parameterlist'}}) {
  359.         print " <b>".$parameter."</b>";
  360. if ($count != $#{$args{'parameterlist'}}) {
  361.     $count++;
  362.     print ",n";
  363. }
  364. print "<br>";
  365.     }
  366.     print "};<br>n";
  367.     print "<h3>Constants</h3>n";
  368.     print "<dl>n";
  369.     foreach $parameter (@{$args{'parameterlist'}}) {
  370. print "<dt><b>".$parameter."</b>n";
  371. print "<dd>";
  372. output_highlight($args{'parameterdescs'}{$parameter});
  373.     }
  374.     print "</dl>n";
  375.     output_section_html(@_);
  376.     print "<hr>n";
  377. }
  378. # output tyepdef in html
  379. sub output_typedef_html(%) {
  380.     my %args = %{$_[0]};
  381.     my ($parameter);
  382.     my $count;
  383.     print "<h2>typedef ".$args{'typedef'}."</h2>n";
  384.     print "<b>typedef ".$args{'typedef'}."</b>n";
  385.     output_section_html(@_);
  386.     print "<hr>n";
  387. }
  388. # output struct in html
  389. sub output_struct_html(%) {
  390.     my %args = %{$_[0]};
  391.     my ($parameter);
  392.     print "<h2>".$args{'type'}." ".$args{'struct'}."</h2>n";
  393.     print "<b>".$args{'type'}." ".$args{'struct'}."</b> {<br>n";
  394.     foreach $parameter (@{$args{'parameterlist'}}) {
  395.         ($args{'parameterdescs'}{$parameter} ne $undescribed) || next;
  396. $type = $args{'parametertypes'}{$parameter};
  397. if ($type =~ m/([^(]*(*)s*)s*(([^)]*))/) {
  398.     # pointer-to-function
  399.     print " <i>$1</i><b>$parameter</b>) <i>($2)</i>;<br>n";
  400. } elsif ($type =~ m/^(.*?)s*(:.*)/) {
  401.     print " <i>$1</i> <b>$parameter</b>$2;<br>n";
  402. } else {
  403.     print " <i>$type</i> <b>$parameter</b>;<br>n";
  404. }
  405.     }
  406.     print "};<br>n";
  407.     print "<h3>Members</h3>n";
  408.     print "<dl>n";
  409.     foreach $parameter (@{$args{'parameterlist'}}) {
  410.         ($args{'parameterdescs'}{$parameter} ne $undescribed) || next;
  411. print "<dt><b>".$parameter."</b>n";
  412. print "<dd>";
  413. output_highlight($args{'parameterdescs'}{$parameter});
  414.     }
  415.     print "</dl>n";
  416.     output_section_html(@_);
  417.     print "<hr>n";
  418. }
  419. # output function in html
  420. sub output_function_html(%) {
  421.     my %args = %{$_[0]};
  422.     my ($parameter, $section);
  423.     my $count;
  424.     print "<h2>Function</h2>n";
  425.     print "<i>".$args{'functiontype'}."</i>n";
  426.     print "<b>".$args{'function'}."</b>n";
  427.     print "(";
  428.     $count = 0;
  429.     foreach $parameter (@{$args{'parameterlist'}}) {
  430. $type = $args{'parametertypes'}{$parameter};
  431. if ($type =~ m/([^(]*(*)s*)s*(([^)]*))/) {
  432.     # pointer-to-function
  433.     print "<i>$1</i><b>$parameter</b>) <i>($2)</i>";
  434. } else {
  435.     print "<i>".$type."</i> <b>".$parameter."</b>";
  436. }
  437. if ($count != $#{$args{'parameterlist'}}) {
  438.     $count++;
  439.     print ",n";
  440. }
  441.     }
  442.     print ")n";
  443.     print "<h3>Arguments</h3>n";
  444.     print "<dl>n";
  445.     foreach $parameter (@{$args{'parameterlist'}}) {
  446.         ($args{'parameterdescs'}{$parameter} ne $undescribed) || next;
  447. print "<dt><b>".$parameter."</b>n";
  448. print "<dd>";
  449. output_highlight($args{'parameterdescs'}{$parameter});
  450.     }
  451.     print "</dl>n";
  452.     output_section_html(@_);
  453.     print "<hr>n";
  454. }
  455. # output intro in html
  456. sub output_intro_html(%) {
  457.     my %args = %{$_[0]};
  458.     my ($parameter, $section);
  459.     my $count;
  460.     foreach $section (@{$args{'sectionlist'}}) {
  461. print "<h3>$section</h3>n";
  462. print "<ul>n";
  463. output_highlight($args{'sections'}{$section});
  464. print "</ul>n";
  465.     }
  466.     print "<hr>n";
  467. }
  468. sub output_section_sgml(%) {
  469.     my %args = %{$_[0]};
  470.     my $section;    
  471.     # print out each section
  472.     $lineprefix="   ";
  473.     foreach $section (@{$args{'sectionlist'}}) {
  474. print "<refsect1>n <title>$section</title>n <para>n";
  475. if ($section =~ m/EXAMPLE/i) {
  476.     print "<example><para>n";
  477. }
  478. output_highlight($args{'sections'}{$section});
  479. if ($section =~ m/EXAMPLE/i) {
  480.     print "</para></example>n";
  481. }
  482. print " </para>n</refsect1>n";
  483.     }
  484. }
  485. # output function in sgml DocBook
  486. sub output_function_sgml(%) {
  487.     my %args = %{$_[0]};
  488.     my ($parameter, $section);
  489.     my $count;
  490.     my $id;
  491.     $id = "API-".$args{'function'};
  492.     $id =~ s/[^A-Za-z0-9]/-/g;
  493.     print "<refentry>n";
  494.     print "<refmeta>n";
  495.     print "<refentrytitle><phrase id="$id">".$args{'function'}."</phrase></refentrytitle>n";
  496.     print "</refmeta>n";
  497.     print "<refnamediv>n";
  498.     print " <refname>".$args{'function'}."</refname>n";
  499.     print " <refpurpose>n";
  500.     print "  ";
  501.     output_highlight ($args{'purpose'});
  502.     print " </refpurpose>n";
  503.     print "</refnamediv>n";
  504.     print "<refsynopsisdiv>n";
  505.     print " <title>Synopsis</title>n";
  506.     print "  <funcsynopsis><funcprototype>n";
  507.     print "   <funcdef>".$args{'functiontype'}." ";
  508.     print "<function>".$args{'function'}." </function></funcdef>n";
  509.     $count = 0;
  510.     if ($#{$args{'parameterlist'}} >= 0) {
  511. foreach $parameter (@{$args{'parameterlist'}}) {
  512.     $type = $args{'parametertypes'}{$parameter};
  513.     if ($type =~ m/([^(]*(*)s*)s*(([^)]*))/) {
  514. # pointer-to-function
  515. print "   <paramdef>$1<parameter>$parameter</parameter>)n";
  516. print "     <funcparams>$2</funcparams></paramdef>n";
  517.     } else {
  518. print "   <paramdef>".$type;
  519. print " <parameter>$parameter</parameter></paramdef>n";
  520.     }
  521. }
  522.     } else {
  523. print "  <void>n";
  524.     }
  525.     print "  </funcprototype></funcsynopsis>n";
  526.     print "</refsynopsisdiv>n";
  527.     # print parameters
  528.     print "<refsect1>n <title>Arguments</title>n";
  529.     if ($#{$args{'parameterlist'}} >= 0) {
  530. print " <variablelist>n";
  531. foreach $parameter (@{$args{'parameterlist'}}) {
  532.     print "  <varlistentry>n   <term><parameter>$parameter</parameter></term>n";
  533.     print "   <listitem>n    <para>n";
  534.     $lineprefix="     ";
  535.     output_highlight($args{'parameterdescs'}{$parameter});
  536.     print "    </para>n   </listitem>n  </varlistentry>n";
  537. }
  538. print " </variablelist>n";
  539.     } else {
  540. print " <para>n  Nonen </para>n";
  541.     }
  542.     print "</refsect1>n";
  543.     output_section_sgml(@_);
  544.     print "</refentry>nn";
  545. }
  546. # output struct in sgml DocBook
  547. sub output_struct_sgml(%) {
  548.     my %args = %{$_[0]};
  549.     my ($parameter, $section);
  550.     my $id;
  551.     $id = "API-struct-".$args{'struct'};
  552.     $id =~ s/[^A-Za-z0-9]/-/g;
  553.     print "<refentry>n";
  554.     print "<refmeta>n";
  555.     print "<refentrytitle><phrase id="$id">".$args{'type'}." ".$args{'struct'}."</phrase></refentrytitle>n";
  556.     print "</refmeta>n";
  557.     print "<refnamediv>n";
  558.     print " <refname>".$args{'type'}." ".$args{'struct'}."</refname>n";
  559.     print " <refpurpose>n";
  560.     print "  ";
  561.     output_highlight ($args{'purpose'});
  562.     print " </refpurpose>n";
  563.     print "</refnamediv>n";
  564.     print "<refsynopsisdiv>n";
  565.     print " <title>Synopsis</title>n";
  566.     print "  <programlisting>n";
  567.     print $args{'type'}." ".$args{'struct'}." {n";
  568.     foreach $parameter (@{$args{'parameterlist'}}) {
  569.         ($args{'parameterdescs'}{$parameter} ne $undescribed) || next;
  570. $type = $args{'parametertypes'}{$parameter};
  571. if ($type =~ m/([^(]*(*)s*)s*(([^)]*))/) {
  572.     # pointer-to-function
  573.     print "  $1 $parameter ($2);n";
  574. } elsif ($type =~ m/^(.*?)s*(:.*)/) {
  575.     print "  $1 $parameter$2;n";
  576. } else {
  577.     print "  ".$type." ".$parameter.";n";
  578. }
  579.     }
  580.     print "};";
  581.     print "  </programlisting>n";
  582.     print "</refsynopsisdiv>n";
  583.     print " <refsect1>n";
  584.     print "  <title>Members</title>n";
  585.     print "  <variablelist>n";
  586.     foreach $parameter (@{$args{'parameterlist'}}) {
  587.       ($args{'parameterdescs'}{$parameter} ne $undescribed) || next;
  588.       print "    <varlistentry>";
  589.       print "      <term>$parameter</term>n";
  590.       print "      <listitem><para>n";
  591.       output_highlight($args{'parameterdescs'}{$parameter});
  592.       print "      </para></listitem>n";
  593.       print "    </varlistentry>n";
  594.     }
  595.     print "  </variablelist>n";
  596.     print " </refsect1>n";
  597.     output_section_sgml(@_);
  598.     print "</refentry>nn";
  599. }
  600. # output enum in sgml DocBook
  601. sub output_enum_sgml(%) {
  602.     my %args = %{$_[0]};
  603.     my ($parameter, $section);
  604.     my $count;
  605.     my $id;
  606.     $id = "API-enum-".$args{'enum'};
  607.     $id =~ s/[^A-Za-z0-9]/-/g;
  608.     print "<refentry>n";
  609.     print "<refmeta>n";
  610.     print "<refentrytitle><phrase id="$id">enum ".$args{'enum'}."</phrase></refentrytitle>n";
  611.     print "</refmeta>n";
  612.     print "<refnamediv>n";
  613.     print " <refname>enum ".$args{'enum'}."</refname>n";
  614.     print " <refpurpose>n";
  615.     print "  ";
  616.     output_highlight ($args{'purpose'});
  617.     print " </refpurpose>n";
  618.     print "</refnamediv>n";
  619.     print "<refsynopsisdiv>n";
  620.     print " <title>Synopsis</title>n";
  621.     print "  <programlisting>n";
  622.     print "enum ".$args{'enum'}." {n";
  623.     $count = 0;
  624.     foreach $parameter (@{$args{'parameterlist'}}) {
  625.         print "  $parameter";
  626.         if ($count != $#{$args{'parameterlist'}}) {
  627.     $count++;
  628.     print ",";
  629.         }
  630. print "n";
  631.     }
  632.     print "};";
  633.     print "  </programlisting>n";
  634.     print "</refsynopsisdiv>n";
  635.     print "<refsect1>n";
  636.     print " <title>Constants</title>n";    
  637.     print "  <variablelist>n";
  638.     foreach $parameter (@{$args{'parameterlist'}}) {
  639.       print "    <varlistentry>";
  640.       print "      <term>$parameter</term>n";
  641.       print "      <listitem><para>n";
  642.       output_highlight($args{'parameterdescs'}{$parameter});
  643.       print "      </para></listitem>n";
  644.       print "    </varlistentry>n";
  645.     }
  646.     print "  </variablelist>n";
  647.     print "</refsect1>n";
  648.     output_section_sgml(@_);
  649.     print "</refentry>nn";
  650. }
  651. # output typedef in sgml DocBook
  652. sub output_typedef_sgml(%) {
  653.     my %args = %{$_[0]};
  654.     my ($parameter, $section);
  655.     my $id;
  656.     $id = "API-typedef-".$args{'typedef'};
  657.     $id =~ s/[^A-Za-z0-9]/-/g;
  658.     print "<refentry>n";
  659.     print "<refmeta>n";
  660.     print "<refentrytitle><phrase id="$id">typedef ".$args{'typedef'}."</phrase></refentrytitle>n";
  661.     print "</refmeta>n";
  662.     print "<refnamediv>n";
  663.     print " <refname>typedef ".$args{'typedef'}."</refname>n";
  664.     print " <refpurpose>n";
  665.     print "  ";
  666.     output_highlight ($args{'purpose'});
  667.     print " </refpurpose>n";
  668.     print "</refnamediv>n";
  669.     print "<refsynopsisdiv>n";
  670.     print " <title>Synopsis</title>n";
  671.     print "  <synopsis>typedef ".$args{'typedef'}.";</synopsis>n";
  672.     print "</refsynopsisdiv>n";
  673.     output_section_sgml(@_);
  674.     print "</refentry>nn";
  675. }
  676. # output in sgml DocBook
  677. sub output_intro_sgml(%) {
  678.     my %args = %{$_[0]};
  679.     my ($parameter, $section);
  680.     my $count;
  681.     my $id = $args{'module'};
  682.     $id =~ s/[^A-Za-z0-9]/-/g;
  683.     # print out each section
  684.     $lineprefix="   ";
  685.     foreach $section (@{$args{'sectionlist'}}) {
  686. print "<refsect1>n <title>$section</title>n <para>n";
  687. if ($section =~ m/EXAMPLE/i) {
  688.     print "<example><para>n";
  689. }
  690. output_highlight($args{'sections'}{$section});
  691. if ($section =~ m/EXAMPLE/i) {
  692.     print "</para></example>n";
  693. }
  694. print " </para>n</refsect1>n";
  695.     }
  696.     print "nn";
  697. }
  698. # output in sgml DocBook
  699. sub output_function_gnome {
  700.     my %args = %{$_[0]};
  701.     my ($parameter, $section);
  702.     my $count;
  703.     my $id;
  704.     $id = $args{'module'}."-".$args{'function'};
  705.     $id =~ s/[^A-Za-z0-9]/-/g;
  706.     print "<sect2>n";
  707.     print " <title id="$id">".$args{'function'}."</title>n";
  708.     print "  <funcsynopsis>n";
  709.     print "   <funcdef>".$args{'functiontype'}." ";
  710.     print "<function>".$args{'function'}." ";
  711.     print "</function></funcdef>n";
  712.     $count = 0;
  713.     if ($#{$args{'parameterlist'}} >= 0) {
  714. foreach $parameter (@{$args{'parameterlist'}}) {
  715.     $type = $args{'parametertypes'}{$parameter};
  716.     if ($type =~ m/([^(]*(*)s*)s*(([^)]*))/) {
  717. # pointer-to-function
  718. print "   <paramdef>$1 <parameter>$parameter</parameter>)n";
  719. print "     <funcparams>$2</funcparams></paramdef>n";
  720.     } else {
  721. print "   <paramdef>".$type;
  722. print " <parameter>$parameter</parameter></paramdef>n";
  723.     }
  724. }
  725.     } else {
  726. print "  <void>n";
  727.     }
  728.     print "  </funcsynopsis>n";
  729.     if ($#{$args{'parameterlist'}} >= 0) {
  730. print " <informaltable pgwide="1" frame="none" role="params">n";
  731. print "<tgroup cols="2">n";
  732. print "<colspec colwidth="2*">n";
  733. print "<colspec colwidth="8*">n";
  734. print "<tbody>n";
  735. foreach $parameter (@{$args{'parameterlist'}}) {
  736.     print "  <row><entry align="right"><parameter>$parameter</parameter></entry>n";
  737.     print "   <entry>n";
  738.     $lineprefix="     ";
  739.     output_highlight($args{'parameterdescs'}{$parameter});
  740.     print "    </entry></row>n";
  741. }
  742. print " </tbody></tgroup></informaltable>n";
  743.     } else {
  744. print " <para>n  Nonen </para>n";
  745.     }
  746.     # print out each section
  747.     $lineprefix="   ";
  748.     foreach $section (@{$args{'sectionlist'}}) {
  749. print "<simplesect>n <title>$section</title>n";
  750. if ($section =~ m/EXAMPLE/i) {
  751.     print "<example><programlisting>n";
  752. } else {
  753. }
  754. print "<para>n";
  755. output_highlight($args{'sections'}{$section});
  756. print "</para>n";
  757. if ($section =~ m/EXAMPLE/i) {
  758.     print "</programlisting></example>n";
  759. } else {
  760. }
  761. print " </simplesect>n";
  762.     }
  763.     print "</sect2>nn";
  764. }
  765. ##
  766. # output function in man
  767. sub output_function_man(%) {
  768.     my %args = %{$_[0]};
  769.     my ($parameter, $section);
  770.     my $count;
  771.     print ".TH "$args{'module'}" 9 "$args{'function'}" "$man_date" "API Manual" LINUXn";
  772.     print ".SH NAMEn";
  773.     print $args{'function'}." \- ".$args{'purpose'}."n";
  774.     print ".SH SYNOPSISn";
  775.     print ".B "".$args{'functiontype'}."" ".$args{'function'}."n";
  776.     $count = 0;
  777.     my $parenth = "(";
  778.     my $post = ",";
  779.     foreach my $parameter (@{$args{'parameterlist'}}) {
  780. if ($count == $#{$args{'parameterlist'}}) {
  781.     $post = ");";
  782. }
  783. $type = $args{'parametertypes'}{$parameter};
  784. if ($type =~ m/([^(]*(*)s*)s*(([^)]*))/) {
  785.     # pointer-to-function
  786.     print ".BI "".$parenth.$1."" ".$parameter." ") (".$2.")".$post.""n";
  787. } else {
  788.     $type =~ s/([^*])$/$1 /;
  789.     print ".BI "".$parenth.$type."" ".$parameter." "".$post.""n";
  790. }
  791. $count++;
  792. $parenth = "";
  793.     }
  794.     print ".SH Argumentsn";
  795.     foreach $parameter (@{$args{'parameterlist'}}) {
  796. print ".IP "".$parameter."" 12n";
  797. output_highlight($args{'parameterdescs'}{$parameter});
  798.     }
  799.     foreach $section (@{$args{'sectionlist'}}) {
  800. print ".SH "$section"n";
  801. output_highlight($args{'sections'}{$section});
  802.     }
  803. }
  804. ##
  805. # output enum in man
  806. sub output_enum_man(%) {
  807.     my %args = %{$_[0]};
  808.     my ($parameter, $section);
  809.     my $count;
  810.     print ".TH "$args{'module'}" 9 "enum $args{'enum'}" "$man_date" "API Manual" LINUXn";
  811.     print ".SH NAMEn";
  812.     print "enum ".$args{'enum'}." \- ".$args{'purpose'}."n";
  813.     print ".SH SYNOPSISn";
  814.     print "enum ".$args{'enum'}." {n";
  815.     $count = 0;
  816.     foreach my $parameter (@{$args{'parameterlist'}}) {
  817.         print ".brn.BI "    $parameter"n";
  818. if ($count == $#{$args{'parameterlist'}}) {
  819.     print "n};n";
  820.     last;
  821. }
  822. else {
  823.     print ", n.brn";
  824. }
  825. $count++;
  826.     }
  827.     print ".SH Constantsn";
  828.     foreach $parameter (@{$args{'parameterlist'}}) {
  829. print ".IP "".$parameter."" 12n";
  830. output_highlight($args{'parameterdescs'}{$parameter});
  831.     }
  832.     foreach $section (@{$args{'sectionlist'}}) {
  833. print ".SH "$section"n";
  834. output_highlight($args{'sections'}{$section});
  835.     }
  836. }
  837. ##
  838. # output struct in man
  839. sub output_struct_man(%) {
  840.     my %args = %{$_[0]};
  841.     my ($parameter, $section);
  842.     print ".TH "$args{'module'}" 9 "".$args{'type'}." ".$args{'struct'}."" "$man_date" "API Manual" LINUXn";
  843.     print ".SH NAMEn";
  844.     print $args{'type'}." ".$args{'struct'}." \- ".$args{'purpose'}."n";
  845.     print ".SH SYNOPSISn";
  846.     print $args{'type'}." ".$args{'struct'}." {n";
  847.     foreach my $parameter (@{$args{'parameterlist'}}) {
  848.         ($args{'parameterdescs'}{$parameter} ne $undescribed) || next;
  849. print "n.brn";
  850. $type = $args{'parametertypes'}{$parameter};
  851. if ($type =~ m/([^(]*(*)s*)s*(([^)]*))/) {
  852.     # pointer-to-function
  853.     print ".BI "    ".$1."" ".$parameter." ") (".$2.")".""n;n";
  854. } elsif ($type =~ m/^(.*?)s*(:.*)/) {
  855.     print ".BI "    ".$1."" ".$parameter.$2." "".""n;n";
  856. } else {
  857.     $type =~ s/([^*])$/$1 /;
  858.     print ".BI "    ".$type."" ".$parameter." "".""n;n";
  859. }
  860. print "n.brn";
  861.     }
  862.     print "};n.brn";
  863.     print ".SH Argumentsn";
  864.     foreach $parameter (@{$args{'parameterlist'}}) {
  865.         ($args{'parameterdescs'}{$parameter} ne $undescribed) || next;
  866. print ".IP "".$parameter."" 12n";
  867. output_highlight($args{'parameterdescs'}{$parameter});
  868.     }
  869.     foreach $section (@{$args{'sectionlist'}}) {
  870. print ".SH "$section"n";
  871. output_highlight($args{'sections'}{$section});
  872.     }
  873. }
  874. ##
  875. # output typedef in man
  876. sub output_typedef_man(%) {
  877.     my %args = %{$_[0]};
  878.     my ($parameter, $section);
  879.     print ".TH "$args{'module'}" 9 "$args{'typedef'}" "$man_date" "API Manual" LINUXn";
  880.     print ".SH NAMEn";
  881.     print "typedef ".$args{'typedef'}." \- ".$args{'purpose'}."n";
  882.     foreach $section (@{$args{'sectionlist'}}) {
  883. print ".SH "$section"n";
  884. output_highlight($args{'sections'}{$section});
  885.     }
  886. }
  887. sub output_intro_man(%) {
  888.     my %args = %{$_[0]};
  889.     my ($parameter, $section);
  890.     my $count;
  891.     print ".TH "$args{'module'}" 9 "$args{'module'}" "$man_date" "API Manual" LINUXn";
  892.     foreach $section (@{$args{'sectionlist'}}) {
  893. print ".SH "$section"n";
  894. output_highlight($args{'sections'}{$section});
  895.     }
  896. }
  897. ##
  898. # output in text
  899. sub output_function_text(%) {
  900.     my %args = %{$_[0]};
  901.     my ($parameter, $section);
  902.     print "Function:nn";
  903.     my $start=$args{'functiontype'}." ".$args{'function'}." (";
  904.     print $start;
  905.     my $count = 0;
  906.     foreach my $parameter (@{$args{'parameterlist'}}) {
  907. $type = $args{'parametertypes'}{$parameter};
  908. if ($type =~ m/([^(]*(*)s*)s*(([^)]*))/) {
  909.     # pointer-to-function
  910.     print $1.$parameter.") (".$2;
  911. } else {
  912.     print $type." ".$parameter;
  913. }
  914. if ($count != $#{$args{'parameterlist'}}) {
  915.     $count++;
  916.     print ",n";
  917.     print " " x length($start);
  918. } else {
  919.     print ");nn";
  920. }
  921.     }
  922.     print "Arguments:nn";
  923.     foreach $parameter (@{$args{'parameterlist'}}) {
  924. print $parameter."nt".$args{'parameterdescs'}{$parameter}."n";
  925.     }
  926.     output_section_text(@_);
  927. }
  928. #output sections in text
  929. sub output_section_text(%) {
  930.     my %args = %{$_[0]};
  931.     my $section;
  932.     print "n";
  933.     foreach $section (@{$args{'sectionlist'}}) {
  934. print "$section:nn";
  935. output_highlight($args{'sections'}{$section});
  936.     }  
  937.     print "nn";
  938. }
  939. # output enum in text
  940. sub output_enum_text(%) {
  941.     my %args = %{$_[0]};
  942.     my ($parameter);
  943.     my $count;
  944.     print "Enum:nn";
  945.     print "enum ".$args{'enum'}." {n";
  946.     $count = 0;
  947.     foreach $parameter (@{$args{'parameterlist'}}) {
  948.         print "t$parameter";
  949. if ($count != $#{$args{'parameterlist'}}) {
  950.     $count++;
  951.     print ",";
  952. }
  953. print "n";
  954.     }
  955.     print "};nn";
  956.     print "Constants:nn";
  957.     foreach $parameter (@{$args{'parameterlist'}}) {
  958. print "$parameternt";
  959. print $args{'parameterdescs'}{$parameter}."n";
  960.     }
  961.     output_section_text(@_);
  962. }
  963. # output typedef in text
  964. sub output_typedef_text(%) {
  965.     my %args = %{$_[0]};
  966.     my ($parameter);
  967.     my $count;
  968.     print "Typedef:nn";
  969.     print "typedef ".$args{'typedef'}."n";
  970.     output_section_text(@_);
  971. }
  972. # output struct as text
  973. sub output_struct_text(%) {
  974.     my %args = %{$_[0]};
  975.     my ($parameter);
  976.     print $args{'type'}." ".$args{'struct'}.":nn";
  977.     print $args{'type'}." ".$args{'struct'}." {n";
  978.     foreach $parameter (@{$args{'parameterlist'}}) {
  979.         ($args{'parameterdescs'}{$parameter} ne $undescribed) || next;
  980. $type = $args{'parametertypes'}{$parameter};
  981. if ($type =~ m/([^(]*(*)s*)s*(([^)]*))/) {
  982.     # pointer-to-function
  983.     print "t$1 $parameter) ($2);n";
  984. } elsif ($type =~ m/^(.*?)s*(:.*)/) {
  985.     print "t$1 $parameter$2;n";
  986. } else {
  987.     print "t".$type." ".$parameter.";n";
  988. }
  989.     }
  990.     print "};nn";
  991.     print "Members:nn";
  992.     foreach $parameter (@{$args{'parameterlist'}}) {
  993.         ($args{'parameterdescs'}{$parameter} ne $undescribed) || next;
  994. print "$parameternt";
  995. print $args{'parameterdescs'}{$parameter}."n";
  996.     }
  997.     print "n";
  998.     output_section_text(@_);
  999. }
  1000. sub output_intro_text(%) {
  1001.     my %args = %{$_[0]};
  1002.     my ($parameter, $section);
  1003.     foreach $section (@{$args{'sectionlist'}}) {
  1004. print " $section:n";
  1005. print "    -> ";
  1006. output_highlight($args{'sections'}{$section});
  1007.     }
  1008. }
  1009. ##
  1010. # generic output function for typedefs
  1011. sub output_declaration {
  1012.     no strict 'refs';
  1013.     my $name = shift;
  1014.     my $functype = shift;
  1015.     my $func = "output_${functype}_$output_mode";
  1016.     if (($function_only==0) || 
  1017. ( $function_only == 1 && defined($function_table{$name})) || 
  1018. ( $function_only == 2 && !defined($function_table{$name})))
  1019.     {
  1020.         &$func(@_);
  1021.     }
  1022. }
  1023. ##
  1024. # generic output function - calls the right one based
  1025. # on current output mode.
  1026. sub output_intro {
  1027.     no strict 'refs';
  1028.     my $func = "output_intro_".$output_mode;
  1029.     &$func(@_);
  1030. }
  1031. ##
  1032. # takes a declaration (struct, union, enum, typedef) and 
  1033. # invokes the right handler. NOT called for functions.
  1034. sub dump_declaration($$) {
  1035.     no strict 'refs';
  1036.     my ($prototype, $file) = @_;
  1037.     my $func = "dump_".$decl_type;
  1038.     &$func(@_);
  1039. }
  1040. sub dump_union($$) {
  1041.     dump_struct(@_);
  1042. }
  1043. sub dump_struct($$) {
  1044.     my $x = shift;
  1045.     my $file = shift;
  1046.     if ($x =~/(struct|union)s+(w+)s*{(.*)}/) {
  1047.         $declaration_name = $2;
  1048.         my $members = $3;
  1049. # ignore embedded structs or unions
  1050. $members =~ s/{.*}//g;
  1051. create_parameterlist($members, ';');
  1052. output_declaration($declaration_name,
  1053.    'struct',
  1054.    {'struct' => $declaration_name,
  1055.     'module' => $modulename,
  1056.     'parameterlist' => @parameterlist,
  1057.     'parameterdescs' => %parameterdescs,
  1058.     'parametertypes' => %parametertypes,
  1059.     'sectionlist' => @sectionlist,
  1060.     'sections' => %sections,
  1061.     'purpose' => $declaration_purpose,
  1062.     'type' => $decl_type
  1063.    });
  1064.     }
  1065.     else {
  1066.         print STDERR "Cannot parse struct or union!n";
  1067.     }
  1068. }
  1069. sub dump_enum($$) {
  1070.     my $x = shift;
  1071.     my $file = shift;
  1072.     if ($x =~ /enums+(w+)s*{(.*)}/) {
  1073.         $declaration_name = $1;
  1074.         my $members = $2;
  1075. foreach my $arg (split ',', $members) {
  1076.     $arg =~ s/^s*(w+).*/$1/;
  1077.     push @parameterlist, $arg;
  1078.     if (!$parameterdescs{$arg}) {
  1079.         $parameterdescs{$arg} = $undescribed;
  1080.         print STDERR "Warning($file:$.): Enum value '$arg' ".
  1081.     "described in enum '$declaration_name'n";
  1082.     }
  1083. }
  1084. output_declaration($declaration_name,
  1085.    'enum',
  1086.    {'enum' => $declaration_name,
  1087.     'module' => $modulename,
  1088.     'parameterlist' => @parameterlist,
  1089.     'parameterdescs' => %parameterdescs,
  1090.     'sectionlist' => @sectionlist,
  1091.     'sections' => %sections,
  1092.     'purpose' => $declaration_purpose
  1093.    });
  1094.     }
  1095.     else {
  1096.         print STDERR "Cannot parse enum!n";
  1097.     }
  1098. }
  1099. sub dump_typedef($$) {
  1100.     my $x = shift;
  1101.     my $file = shift;
  1102.     while (($x =~ /(*.)s*;$/) || ($x =~ /[*.]s*;$/)) {
  1103.         $x =~ s/(*.)s*;$/;/;
  1104. $x =~ s/[*.]s*;$/;/;
  1105.     }
  1106.     if ($x =~ /typedef.*s+(w+)s*;/) {
  1107.         $declaration_name = $1;
  1108. output_declaration($declaration_name,
  1109.    'typedef',
  1110.    {'typedef' => $declaration_name,
  1111.     'module' => $modulename,
  1112.     'sectionlist' => @sectionlist,
  1113.     'sections' => %sections,
  1114.     'purpose' => $declaration_purpose
  1115.    });
  1116.     }
  1117.     else {
  1118.         print STDERR "Cannot parse typedef!n";
  1119.     }
  1120. }
  1121. sub create_parameterlist($$) {
  1122.     my $args = shift;
  1123.     my $splitter = shift;
  1124.     my $type;
  1125.     my $param;
  1126.     while ($args =~ /(([^),]+),/) {
  1127.         $args =~ s/(([^),]+),/$1#/g;
  1128.     }
  1129.     
  1130.     foreach my $arg (split($splitter, $args)) {
  1131.         # strip leading/trailing spaces
  1132.         $arg =~ s/^s*//;
  1133. $arg =~ s/s*$//;
  1134. $arg =~ s/s+/ /;
  1135. if ($arg =~ m/(/) {
  1136.     # pointer-to-function
  1137.     $arg =~ tr/#/,/;
  1138.     $arg =~ m/[^(]+(*([^)]+))/;
  1139.     $param = $1;
  1140.     $type = $arg;
  1141.     $type =~ s/([^(]+(*)$param/$1/;
  1142. } else {
  1143.     # evil magic to get fixed array parameters to work
  1144.     $arg =~ s/(.+s+)(.+)[.*/$1* $2/;
  1145.     my @args = split('s', $arg);
  1146.     $param = pop @args;
  1147.     if ($param =~ m/^(*+)(.*)/) {
  1148.         $param = $2;
  1149. push @args, $1;
  1150.     } 
  1151.     elsif ($param =~ m/(.*?)s*:s*(d+)/) {
  1152.         $param = $1;
  1153.         push @args, ":$2";
  1154.     }
  1155.     $type = join " ", @args;
  1156. }
  1157. if ($type eq "" && $param eq "...")
  1158. {
  1159.     $type="...";
  1160.     $param="...";
  1161.     $parameterdescs{"..."} = "variable arguments";
  1162. }
  1163. elsif ($type eq "" && ($param eq "" or $param eq "void"))
  1164. {
  1165.     $type="";
  1166.     $param="void";
  1167.     $parameterdescs{void} = "no arguments";
  1168. }
  1169. if (defined $type && $type && !defined $parameterdescs{$param}) {
  1170.     $parameterdescs{$param} = $undescribed;
  1171.     if (($type eq 'function') || ($type eq 'enum')) {
  1172.         print STDERR "Warning($file:$.): Function parameter ".
  1173.     "or member '$param' not " .
  1174.     "described in '$declaration_name'n";
  1175.     }
  1176.     ++$errors;
  1177.         }
  1178. push @parameterlist, $param;
  1179. $parametertypes{$param} = $type;
  1180.     }
  1181. }
  1182. ##
  1183. # takes a function prototype and the name of the current file being
  1184. # processed and spits out all the details stored in the global
  1185. # arrays/hashes.
  1186. sub dump_function($$) {
  1187.     my $prototype = shift;
  1188.     my $file = shift;
  1189.     $prototype =~ s/^static +//;
  1190.     $prototype =~ s/^extern +//;
  1191.     $prototype =~ s/^inline +//;
  1192.     $prototype =~ s/^__inline__ +//;
  1193.     $prototype =~ s/^#define +//; #ak added
  1194.     # Yes, this truly is vile.  We are looking for:
  1195.     # 1. Return type (may be nothing if we're looking at a macro)
  1196.     # 2. Function name
  1197.     # 3. Function parameters.
  1198.     #
  1199.     # All the while we have to watch out for function pointer parameters
  1200.     # (which IIRC is what the two sections are for), C types (these
  1201.     # regexps don't even start to express all the possibilities), and
  1202.     # so on.
  1203.     #
  1204.     # If you mess with these regexps, it's a good idea to check that
  1205.     # the following functions' documentation still comes out right:
  1206.     # - parport_register_device (function pointer parameters)
  1207.     # - atomic_set (macro)
  1208.     # - pci_match_device (long return type)
  1209.     if ($prototype =~ m/^()([a-zA-Z0-9_~:]+)s*(([^(]*))/ ||
  1210. $prototype =~ m/^(w+)s+([a-zA-Z0-9_~:]+)s*(([^(]*))/ ||
  1211. $prototype =~ m/^(w+s**)s*([a-zA-Z0-9_~:]+)s*(([^(]*))/ ||
  1212. $prototype =~ m/^(w+s+w+)s+([a-zA-Z0-9_~:]+)s*(([^(]*))/ ||
  1213. $prototype =~ m/^(w+s+w+s**)s*([a-zA-Z0-9_~:]+)s*(([^(]*))/ ||
  1214. $prototype =~ m/^(w+s+w+s+w+)s+([a-zA-Z0-9_~:]+)s*(([^(]*))/ ||
  1215. $prototype =~ m/^(w+s+w+s+w+s**)s*([a-zA-Z0-9_~:]+)s*(([^(]*))/ ||
  1216. $prototype =~ m/^()([a-zA-Z0-9_~:]+)s*(([^{]*))/ ||
  1217. $prototype =~ m/^(w+)s+([a-zA-Z0-9_~:]+)s*(([^{]*))/ ||
  1218. $prototype =~ m/^(w+s**)s*([a-zA-Z0-9_~:]+)s*(([^{]*))/ ||
  1219. $prototype =~ m/^(w+s+w+)s+([a-zA-Z0-9_~:]+)s*(([^{]*))/ ||
  1220. $prototype =~ m/^(w+s+w+s**)s*([a-zA-Z0-9_~:]+)s*(([^{]*))/ ||
  1221. $prototype =~ m/^(w+s+w+s+w+)s+([a-zA-Z0-9_~:]+)s*(([^{]*))/ ||
  1222. $prototype =~ m/^(w+s+w+s+w+s**)s*([a-zA-Z0-9_~:]+)s*(([^{]*))/)  {
  1223. $return_type = $1;
  1224. $declaration_name = $2;
  1225. my $args = $3;
  1226. create_parameterlist($args, ',');
  1227.     } else {
  1228. print STDERR "Error($.): cannot understand prototype: '$prototype'n";
  1229. ++$errors;
  1230. return;
  1231.     }
  1232.     output_declaration($declaration_name, 
  1233.        'function',
  1234.        {'function' => $declaration_name,
  1235. 'module' => $modulename,
  1236. 'functiontype' => $return_type,
  1237. 'parameterlist' => @parameterlist,
  1238. 'parameterdescs' => %parameterdescs,
  1239. 'parametertypes' => %parametertypes,
  1240. 'sectionlist' => @sectionlist,
  1241. 'sections' => %sections,
  1242. 'purpose' => $declaration_purpose
  1243.        });
  1244. }
  1245. sub process_file($);
  1246. # Read the file that maps relative names to absolute names for
  1247. # separate source and object directories and for shadow trees.
  1248. if (open(SOURCE_MAP, "<.tmp_filelist.txt")) {
  1249. my ($relname, $absname);
  1250. while(<SOURCE_MAP>) {
  1251. chop();
  1252. ($relname, $absname) = (split())[0..1];
  1253. $relname =~ s:^/+::;
  1254. $source_map{$relname} = $absname;
  1255. }
  1256. close(SOURCE_MAP);
  1257. }
  1258. if ($filelist) {
  1259. open(FLIST,"<$filelist") or die "Can't open file list $filelist";
  1260. while(<FLIST>) {
  1261. chop;
  1262. process_file($_);
  1263. }
  1264. }
  1265. foreach (@ARGV) {
  1266.     chomp;
  1267.     process_file($_);
  1268. }
  1269. exit($errors);
  1270. sub reset_state {
  1271.     $function = "";
  1272.     %constants = ();
  1273.     %parameterdescs = ();
  1274.     %parametertypes = ();
  1275.     @parameterlist = ();
  1276.     %sections = ();
  1277.     @sectionlist = ();
  1278.     $prototype = "";
  1279.     
  1280.     $state = 0;
  1281. }
  1282. sub process_state3_function($) { 
  1283.     my $x = shift;
  1284.     if ($x =~ m#s*/*s+MACDOCs*#io) {
  1285. # do nothing
  1286.     }
  1287.     elsif ($x =~ /([^{]*)/) {
  1288.         $prototype .= $1;
  1289.     }
  1290.     if (($x =~ /{/) || ($x =~ /#/) || ($x =~ /;/)) {
  1291.         $prototype =~ s@/*.*?*/@@gos; # strip comments.
  1292. $prototype =~ s@[rn]+@ @gos; # strip newlines/cr's.
  1293. $prototype =~ s@^s+@@gos; # strip leading spaces
  1294. dump_function($prototype,$file);
  1295. reset_state();
  1296.     }
  1297. }
  1298. sub process_state3_type($) { 
  1299.     my $x = shift;
  1300.     $x =~ s@/*.*?*/@@gos; # strip comments.
  1301.     $x =~ s@[rn]+@ @gos; # strip newlines/cr's.
  1302.     $x =~ s@^s+@@gos; # strip leading spaces
  1303.     $x =~ s@s+$@@gos; # strip trailing spaces
  1304.     while (1) {
  1305.         if ( $x =~ /([^{};]*)([{};])(.*)/ ) {
  1306.     $prototype .= $1 . $2;
  1307.     ($2 eq '{') && $brcount++;
  1308.     ($2 eq '}') && $brcount--;
  1309.     if (($2 eq ';') && ($brcount == 0)) {
  1310.         dump_declaration($prototype,$file);
  1311. reset_state();
  1312.         last;
  1313.     }
  1314.     $x = $3;
  1315.         } else {
  1316.     $prototype .= $x;
  1317.     last;
  1318. }
  1319.     }
  1320. }
  1321. sub process_file($) {
  1322.     my ($file) = @_;
  1323.     my $identifier;
  1324.     my $func;
  1325.     if (defined($source_map{$file})) {
  1326. $file = $source_map{$file};
  1327.     }
  1328.     if (!open(IN,"<$file")) {
  1329. print STDERR "Error: Cannot open file $filen";
  1330. ++$errors;
  1331. return;
  1332.     }
  1333.     while (<IN>) {
  1334. if ($state == 0) {
  1335.     if (/$doc_start/o) {
  1336. $state = 1; # next line is always the function name
  1337.     }
  1338. } elsif ($state == 1) { # this line is the function name (always)
  1339.     if (/$doc_block/o) {
  1340. $state = 4;
  1341. $contents = "";
  1342. if ( $1 eq "" ) {
  1343. $section = $section_intro;
  1344. } else {
  1345. $section = $1;
  1346. }
  1347.             }
  1348.     elsif (/$doc_decl/o) {
  1349. $identifier = $1;
  1350. if (/s*([ws]+?)s*-/) {
  1351.     $identifier = $1;
  1352. }
  1353. $state = 2;
  1354. if (/-(.*)/) {
  1355.     $declaration_purpose = $1;
  1356. } else {
  1357.     $declaration_purpose = "";
  1358. }
  1359. if ($identifier =~ m/^struct/) {
  1360.     $decl_type = 'struct';
  1361. } elsif ($identifier =~ m/^union/) {
  1362.     $decl_type = 'union';
  1363. } elsif ($identifier =~ m/^enum/) {
  1364.     $decl_type = 'enum';
  1365. } elsif ($identifier =~ m/^typedef/) {
  1366.     $decl_type = 'typedef';
  1367. } else {
  1368.     $decl_type = 'function';
  1369. }
  1370. if ($verbose) {
  1371.     print STDERR "Info($.): Scanning doc for $identifiern";
  1372. }
  1373.     } else {
  1374. print STDERR "WARN($.): Cannot understand $_ on line $.",
  1375. " - I thought it was a doc linen";
  1376. ++$errors;
  1377. $state = 0;
  1378.     }
  1379. } elsif ($state == 2) { # look for head: lines, and include content
  1380.     if (/$doc_sect/o) {
  1381. $newsection = $1;
  1382. $newcontents = $2;
  1383. if ($contents ne "") {
  1384.     $contents =~ s/&/\\\amp;/g;
  1385.     $contents =~ s/</\\\lt;/g;
  1386.     $contents =~ s/>/\\\gt;/g;
  1387.     dump_section($section, $contents);
  1388.     $section = $section_default;
  1389. }
  1390. $contents = $newcontents;
  1391. if ($contents ne "") {
  1392.     $contents .= "n";
  1393. }
  1394. $section = $newsection;
  1395.     } elsif (/$doc_end/) {
  1396. if ($contents ne "") {
  1397.     $contents =~ s/&/\\\amp;/g;
  1398.     $contents =~ s/</\\\lt;/g;
  1399.     $contents =~ s/>/\\\gt;/g;
  1400.     dump_section($section, $contents);
  1401.     $section = $section_default;
  1402.     $contents = "";
  1403. }
  1404. $prototype = "";
  1405. $state = 3;
  1406. $brcount = 0;
  1407. #     print STDERR "end of doc comment, looking for prototypen";
  1408.     } elsif (/$doc_content/) {
  1409. # miguel-style comment kludge, look for blank lines after
  1410. # @parameter line to signify start of description
  1411. if ($1 eq "" && 
  1412. ($section =~ m/^@/ || $section eq $section_context)) {
  1413.     $contents =~ s/&/\\\amp;/g;
  1414.     $contents =~ s/</\\\lt;/g;
  1415.     $contents =~ s/>/\\\gt;/g;
  1416.     dump_section($section, $contents);
  1417.     $section = $section_default;
  1418.     $contents = "";
  1419. } else {
  1420.     $contents .= $1."n";
  1421. }
  1422.     } else {
  1423. # i dont know - bad line?  ignore.
  1424. print STDERR "WARNING($.): bad line: $_"; 
  1425. ++$errors;
  1426.     }
  1427. } elsif ($state == 3) { # scanning for function { (end of prototype)
  1428.     if ($decl_type eq 'function') {
  1429.         process_state3_function($_);
  1430.     } else {
  1431.         process_state3_type($_);
  1432.     }
  1433. } elsif ($state == 4) {
  1434. # Documentation block
  1435.         if (/$doc_block/) {
  1436. dump_section($section, $contents);
  1437. output_intro({'sectionlist' => @sectionlist,
  1438.       'sections' => %sections });
  1439. $contents = "";
  1440. $function = "";
  1441. %constants = ();
  1442. %parameterdescs = ();
  1443. %parametertypes = ();
  1444. @parameterlist = ();
  1445. %sections = ();
  1446. @sectionlist = ();
  1447. $prototype = "";
  1448. if ( $1 eq "" ) {
  1449. $section = $section_intro;
  1450. } else {
  1451. $section = $1;
  1452. }
  1453.                 }
  1454. elsif (/$doc_end/)
  1455. {
  1456. dump_section($section, $contents);
  1457. output_intro({'sectionlist' => @sectionlist,
  1458.       'sections' => %sections });
  1459. $contents = "";
  1460. $function = "";
  1461. %constants = ();
  1462. %parameterdescs = ();
  1463. %parametertypes = ();
  1464. @parameterlist = ();
  1465. %sections = ();
  1466. @sectionlist = ();
  1467. $prototype = "";
  1468. $state = 0;
  1469. }
  1470. elsif (/$doc_content/)
  1471. {
  1472. if ( $1 eq "" )
  1473. {
  1474. $contents .= $blankline;
  1475. }
  1476. else
  1477. {
  1478. $contents .= $1 . "n";
  1479. }
  1480.          }
  1481.           }
  1482.     }
  1483. }