xref: /netbsd-src/external/gpl2/texinfo/dist/util/gdoc (revision 29619d2afe564e54d657b83e5a3ae89584f83720)
1*29619d2aSchristos#!/usr/bin/perl
2*29619d2aSchristos
3*29619d2aSchristos## Copyright (c) 2002, 2003 Simon Josefsson                      ##
4*29619d2aSchristos##                    added -texinfo, -listfunc                  ##
5*29619d2aSchristos##                    man page revamp                            ##
6*29619d2aSchristos##                    various improvements                       ##
7*29619d2aSchristos## Copyright (c) 1998 Michael Zucchi, All Rights Reserved        ##
8*29619d2aSchristos##                    hacked to allow -tex option --nmav         ##
9*29619d2aSchristos##                                                               ##
10*29619d2aSchristos## This software falls under the GNU Public License. Please read ##
11*29619d2aSchristos##              the COPYING file for more information            ##
12*29619d2aSchristos
13*29619d2aSchristos#
14*29619d2aSchristos# This will read a 'c' file and scan for embedded comments in the
15*29619d2aSchristos# style of gnome comments (+minor extensions - see below).
16*29619d2aSchristos#
17*29619d2aSchristos# This program is modified by Nikos Mavroyanopoulos, for the gnutls
18*29619d2aSchristos# project.
19*29619d2aSchristos
20*29619d2aSchristos# Note: This only supports 'c'.
21*29619d2aSchristos
22*29619d2aSchristos# usage:
23*29619d2aSchristos# gdoc [ -docbook | -html | -text | -man | -tex | -texinfo | -listfunc ]
24*29619d2aSchristos#      [ -sourceversion verno ] [ -includefuncprefix ] [ -bugsto address ]
25*29619d2aSchristos#      [ -seeinfo infonode ] [ -copyright notice ] [ -verbatimcopying ]
26*29619d2aSchristos#      [ -function funcname [ -function funcname ...] ] c file(s)s > outputfil
27*29619d2aSchristose
28*29619d2aSchristos#
29*29619d2aSchristos#  Set output format using one of -docbook, -html, -text, -man, -tex,
30*29619d2aSchristos#  -texinfo, or -listfunc.  Default is man.
31*29619d2aSchristos#
32*29619d2aSchristos#  -sourceversion
33*29619d2aSchristos#       Version number for source code, e.g. '1.0.4'.  Used in 'man' headers.
34*29619d2aSchristos#       Defaults to using current date.
35*29619d2aSchristos#
36*29619d2aSchristos#  -includefuncprefix
37*29619d2aSchristos#       For man pages, generate a #include <FILE.h> based on the function
38*29619d2aSchristos#       prefix.  For example, a function gss_init_sec_context will generate
39*29619d2aSchristos#       an include statement of #include <gss.h>.
40*29619d2aSchristos#
41*29619d2aSchristos#  -bugsto address
42*29619d2aSchristos#       For man pages, include a section about reporting bugs and mention
43*29619d2aSchristos#       the given e-mail address, e.g 'bug-libidn@gnu.org'.
44*29619d2aSchristos#
45*29619d2aSchristos#  -seeinfo infonode
46*29619d2aSchristos#       For man pages, include a section that point to an info manual
47*29619d2aSchristos#       for more information.
48*29619d2aSchristos#
49*29619d2aSchristos#  -copyright notice
50*29619d2aSchristos#       For man pages, include a copyright section with the given
51*29619d2aSchristos#       notice after a preamble.  Use, e.g., '2002, 2003 Simon Josefsson'.
52*29619d2aSchristos#
53*29619d2aSchristos#  -verbatimcopying
54*29619d2aSchristos#       For man pages, and when the -copyright parameter is used,
55*29619d2aSchristos#       add a licensing statement that say verbatim copying is permitted.
56*29619d2aSchristos#
57*29619d2aSchristos#  -function funcname
58*29619d2aSchristos#       If set, then only generate documentation for the given function(s).  A
59*29619d2aSchristosll
60*29619d2aSchristos#       other functions are ignored.
61*29619d2aSchristos#
62*29619d2aSchristos#  c files - list of 'c' files to process
63*29619d2aSchristos#
64*29619d2aSchristos#  All output goes to stdout, with errors to stderr.
65*29619d2aSchristos
66*29619d2aSchristos#
67*29619d2aSchristos# format of comments.
68*29619d2aSchristos# In the following table, (...)? signifies optional structure.
69*29619d2aSchristos#                         (...)* signifies 0 or more structure elements
70*29619d2aSchristos# /**
71*29619d2aSchristos#  * function_name(:)? (- short description)?
72*29619d2aSchristos# (* @parameterx: (description of parameter x)?)*
73*29619d2aSchristos# (* a blank line)?
74*29619d2aSchristos#  * (Description:)? (Description of function)?
75*29619d2aSchristos#  * (Section header: (section description)? )*
76*29619d2aSchristos#  (*)?*/
77*29619d2aSchristos#
78*29619d2aSchristos# So .. the trivial example would be:
79*29619d2aSchristos#
80*29619d2aSchristos# /**
81*29619d2aSchristos#  * my_function
82*29619d2aSchristos#  **/
83*29619d2aSchristos#
84*29619d2aSchristos# If the Description: header tag is ommitted, then there must be a blank line
85*29619d2aSchristos# after the last parameter specification.
86*29619d2aSchristos# e.g.
87*29619d2aSchristos# /**
88*29619d2aSchristos#  * my_function - does my stuff
89*29619d2aSchristos#  * @my_arg: its mine damnit
90*29619d2aSchristos#  *
91*29619d2aSchristos#  * Does my stuff explained.
92*29619d2aSchristos#  */
93*29619d2aSchristos#
94*29619d2aSchristos#  or, could also use:
95*29619d2aSchristos# /**
96*29619d2aSchristos#  * my_function - does my stuff
97*29619d2aSchristos#  * @my_arg: its mine damnit
98*29619d2aSchristos#  * Description: Does my stuff explained.
99*29619d2aSchristos#  */
100*29619d2aSchristos# etc.
101*29619d2aSchristos#
102*29619d2aSchristos# All descriptions can be multiline, apart from the short function description
103*29619d2aSchristos.
104*29619d2aSchristos#
105*29619d2aSchristos# All descriptive text is further processed, scanning for the following specia
106*29619d2aSchristosl
107*29619d2aSchristos# patterns, which are highlighted appropriately.
108*29619d2aSchristos#
109*29619d2aSchristos# 'funcname()' - function
110*29619d2aSchristos# '$ENVVAR' - environmental variable
111*29619d2aSchristos# '&struct_name' - name of a structure
112*29619d2aSchristos# '@parameter' - name of a parameter
113*29619d2aSchristos# '%CONST' - name of a constant.
114*29619d2aSchristos
115*29619d2aSchristos#
116*29619d2aSchristos# Extensions for LaTeX:
117*29619d2aSchristos#
118*29619d2aSchristos# 1. the symbol '->' will be replaced with a rightarrow
119*29619d2aSchristos# 2. x^y with ${x}^{y}$.
120*29619d2aSchristos# 3. xxx\: with xxx:
121*29619d2aSchristos
122*29619d2aSchristosuse POSIX qw(strftime);
123*29619d2aSchristos
124*29619d2aSchristos# match expressions used to find embedded type information
125*29619d2aSchristos$type_constant = "\\\%(\\w+)";
126*29619d2aSchristos$type_func = "(\\w+\\(\\))";
127*29619d2aSchristos$type_param = "\\\@(\\w+)";
128*29619d2aSchristos$type_struct = "\\\&(\\w+)";
129*29619d2aSchristos$type_env = "(\\\$\\w+)";
130*29619d2aSchristos
131*29619d2aSchristos
132*29619d2aSchristos# Output conversion substitutions.
133*29619d2aSchristos#  One for each output format
134*29619d2aSchristos
135*29619d2aSchristos# these work fairly well
136*29619d2aSchristos%highlights_html = ( $type_constant, "<i>\$1</i>",
137*29619d2aSchristos                     $type_func, "<b>\$1</b>",
138*29619d2aSchristos                     $type_struct, "<i>\$1</i>",
139*29619d2aSchristos                     $type_param, "<tt><b>\$1</b></tt>" );
140*29619d2aSchristos$blankline_html = "<p>";
141*29619d2aSchristos
142*29619d2aSchristos%highlights_texinfo = ( $type_constant, "\\\@var{\$1}",
143*29619d2aSchristos                        $type_func, "\\\@code{\$1}",
144*29619d2aSchristos                        $type_struct, "\\\@code{\$1}",
145*29619d2aSchristos                        $type_param, "\\\@code{\$1}" );
146*29619d2aSchristos$blankline_texinfo = "";
147*29619d2aSchristos
148*29619d2aSchristos%highlights_tex = ( $type_constant, "{\\\\it \$1}",
149*29619d2aSchristos                     $type_func, "{\\\\bf \$1}",
150*29619d2aSchristos                     $type_struct, "{\\\\it \$1}",
151*29619d2aSchristos                     $type_param, "{\\\\bf \$1}" );
152*29619d2aSchristos$blankline_tex = "\\\\";
153*29619d2aSchristos
154*29619d2aSchristos# sgml, docbook format
155*29619d2aSchristos%highlights_sgml = ( $type_constant, "<replaceable class=\"option\">\$1</repla
156*29619d2aSchristosceable>",
157*29619d2aSchristos                     $type_func, "<function>\$1</function>",
158*29619d2aSchristos                     $type_struct, "<structname>\$1</structname>",
159*29619d2aSchristos                     $type_env, "<envar>\$1</envar>",
160*29619d2aSchristos                     $type_param, "<parameter>\$1</parameter>" );
161*29619d2aSchristos$blankline_sgml = "</para><para>\n";
162*29619d2aSchristos
163*29619d2aSchristos# these are pretty rough
164*29619d2aSchristos%highlights_man = ( $type_constant, "\\n.I \\\"\$1\\\"\\n",
165*29619d2aSchristos                    $type_func, "\\n.B \\\"\$1\\\"\\n",
166*29619d2aSchristos                    $type_struct, "\\n.I \\\"\$1\\\"\\n",
167*29619d2aSchristos                    $type_param."([\.\, ]*)\n?", "\\n.I \\\"\$1\$2\\\"\\n" );
168*29619d2aSchristos$blankline_man = "";
169*29619d2aSchristos
170*29619d2aSchristos# text-mode
171*29619d2aSchristos%highlights_text = ( $type_constant, "\$1",
172*29619d2aSchristos                     $type_func, "\$1",
173*29619d2aSchristos                     $type_struct, "\$1",
174*29619d2aSchristos                     $type_param, "\$1" );
175*29619d2aSchristos$blankline_text = "";
176*29619d2aSchristos
177*29619d2aSchristos
178*29619d2aSchristossub usage {
179*29619d2aSchristos    print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man | -tex | -texinf
180*29619d2aSchristoso  -listfunc ]\n";
181*29619d2aSchristos    print "         [ -sourceversion verno ] [ -includefuncprefix ]\n";
182*29619d2aSchristos    print "         [ -bugsto address ] [ -seeinfo infonode ] [ -copyright not
183*29619d2aSchristosice]\n";
184*29619d2aSchristos    print "         [ -verbatimcopying ]\n";
185*29619d2aSchristos    print "         [ -function funcname [ -function funcname ...] ]\n";
186*29619d2aSchristos    print "         c source file(s) > outputfile\n";
187*29619d2aSchristos    exit 1;
188*29619d2aSchristos}
189*29619d2aSchristos
190*29619d2aSchristos# read arguments
191*29619d2aSchristosif ($#ARGV==-1) {
192*29619d2aSchristos    usage();
193*29619d2aSchristos}
194*29619d2aSchristos
195*29619d2aSchristos$verbose = 0;
196*29619d2aSchristos$output_mode = "man";
197*29619d2aSchristos%highlights = %highlights_man;
198*29619d2aSchristos$blankline = $blankline_man;
199*29619d2aSchristos$modulename = "API Documentation";
200*29619d2aSchristos$sourceversion = strftime "%Y-%m-%d", localtime;
201*29619d2aSchristos$function_only = 0;
202*29619d2aSchristoswhile ($ARGV[0] =~ m/^-(.*)/) {
203*29619d2aSchristos    $cmd = shift @ARGV;
204*29619d2aSchristos    if ($cmd eq "-html") {
205*29619d2aSchristos        $output_mode = "html";
206*29619d2aSchristos        %highlights = %highlights_html;
207*29619d2aSchristos        $blankline = $blankline_html;
208*29619d2aSchristos    } elsif ($cmd eq "-man") {
209*29619d2aSchristos        $output_mode = "man";
210*29619d2aSchristos        %highlights = %highlights_man;
211*29619d2aSchristos        $blankline = $blankline_man;
212*29619d2aSchristos    } elsif ($cmd eq "-tex") {
213*29619d2aSchristos        $output_mode = "tex";
214*29619d2aSchristos        %highlights = %highlights_tex;
215*29619d2aSchristos        $blankline = $blankline_tex;
216*29619d2aSchristos    } elsif ($cmd eq "-texinfo") {
217*29619d2aSchristos        $output_mode = "texinfo";
218*29619d2aSchristos        %highlights = %highlights_texinfo;
219*29619d2aSchristos        $blankline = $blankline_texinfo;
220*29619d2aSchristos    } elsif ($cmd eq "-text") {
221*29619d2aSchristos        $output_mode = "text";
222*29619d2aSchristos        %highlights = %highlights_text;
223*29619d2aSchristos        $blankline = $blankline_text;
224*29619d2aSchristos    } elsif ($cmd eq "-docbook") {
225*29619d2aSchristos        $output_mode = "sgml";
226*29619d2aSchristos        %highlights = %highlights_sgml;
227*29619d2aSchristos        $blankline = $blankline_sgml;
228*29619d2aSchristos    } elsif ($cmd eq "-listfunc") {
229*29619d2aSchristos        $output_mode = "listfunc";
230*29619d2aSchristos    } elsif ($cmd eq "-module") { # not needed for sgml, inherits from calling
231*29619d2aSchristos document
232*29619d2aSchristos        $modulename = shift @ARGV;
233*29619d2aSchristos    } elsif ($cmd eq "-sourceversion") {
234*29619d2aSchristos        $sourceversion = shift @ARGV;
235*29619d2aSchristos    } elsif ($cmd eq "-includefuncprefix") {
236*29619d2aSchristos        $includefuncprefix = 1;
237*29619d2aSchristos    } elsif ($cmd eq "-bugsto") {
238*29619d2aSchristos        $bugsto = shift @ARGV;
239*29619d2aSchristos    } elsif ($cmd eq "-copyright") {
240*29619d2aSchristos        $copyright = shift @ARGV;
241*29619d2aSchristos    } elsif ($cmd eq "-verbatimcopying") {
242*29619d2aSchristos        $verbatimcopying = 1;
243*29619d2aSchristos    } elsif ($cmd eq "-seeinfo") {
244*29619d2aSchristos        $seeinfo = shift @ARGV;
245*29619d2aSchristos    } elsif ($cmd eq "-function") { # to only output specific functions
246*29619d2aSchristos        $function_only = 1;
247*29619d2aSchristos        $function = shift @ARGV;
248*29619d2aSchristos        $function_table{$function} = 1;
249*29619d2aSchristos    } elsif ($cmd eq "-v") {
250*29619d2aSchristos        $verbose = 1;
251*29619d2aSchristos    } elsif (($cmd eq "-h") || ($cmd eq "--help")) {
252*29619d2aSchristos        usage();
253*29619d2aSchristos    }
254*29619d2aSchristos}
255*29619d2aSchristos
256*29619d2aSchristos##
257*29619d2aSchristos# dumps section contents to arrays/hashes intended for that purpose.
258*29619d2aSchristos#
259*29619d2aSchristossub dump_section {
260*29619d2aSchristos    my $name = shift @_;
261*29619d2aSchristos    my $contents = join "\n", @_;
262*29619d2aSchristos
263*29619d2aSchristos    if ($name =~ m/$type_constant/) {
264*29619d2aSchristos        $name = $1;
265*29619d2aSchristos#       print STDERR "constant section '$1' = '$contents'\n";
266*29619d2aSchristos        $constants{$name} = $contents;
267*29619d2aSchristos    } elsif ($name =~ m/$type_param/) {
268*29619d2aSchristos#       print STDERR "parameter def '$1' = '$contents'\n";
269*29619d2aSchristos        $name = $1;
270*29619d2aSchristos        $parameters{$name} = $contents;
271*29619d2aSchristos    } else {
272*29619d2aSchristos#       print STDERR "other section '$name' = '$contents'\n";
273*29619d2aSchristos        $sections{$name} = $contents;
274*29619d2aSchristos        push @sectionlist, $name;
275*29619d2aSchristos    }
276*29619d2aSchristos}
277*29619d2aSchristos
278*29619d2aSchristos##
279*29619d2aSchristos# output function
280*29619d2aSchristos#
281*29619d2aSchristos# parameters, a hash.
282*29619d2aSchristos#  function => "function name"
283*29619d2aSchristos#  parameterlist => @list of parameters
284*29619d2aSchristos#  parameters => %parameter descriptions
285*29619d2aSchristos#  sectionlist => @list of sections
286*29619d2aSchristos#  sections => %descriont descriptions
287*29619d2aSchristos#
288*29619d2aSchristos
289*29619d2aSchristossub repstr {
290*29619d2aSchristos    $pattern = shift;
291*29619d2aSchristos    $repl = shift;
292*29619d2aSchristos    $match1 = shift;
293*29619d2aSchristos    $match2 = shift;
294*29619d2aSchristos    $match3 = shift;
295*29619d2aSchristos    $match4 = shift;
296*29619d2aSchristos
297*29619d2aSchristos    $output = $repl;
298*29619d2aSchristos    $output =~ s,\$1,$match1,g;
299*29619d2aSchristos    $output =~ s,\$2,$match2,g;
300*29619d2aSchristos    $output =~ s,\$3,$match3,g;
301*29619d2aSchristos    $output =~ s,\$4,$match4,g;
302*29619d2aSchristos
303*29619d2aSchristos    eval "\$return = qq/$output/";
304*29619d2aSchristos
305*29619d2aSchristos#    print "pattern $pattern matched 1=$match1 2=$match2 3=$match3 4=$match4 r
306*29619d2aSchristoseplace $repl yielded $output interpolated $return\n";
307*29619d2aSchristos
308*29619d2aSchristos    $return;
309*29619d2aSchristos}
310*29619d2aSchristos
311*29619d2aSchristossub output_highlight {
312*29619d2aSchristos    my $contents = join "\n", @_;
313*29619d2aSchristos    my $line;
314*29619d2aSchristos
315*29619d2aSchristos    foreach $pattern (keys %highlights) {
316*29619d2aSchristos#       print "scanning pattern $pattern ($highlights{$pattern})\n";
317*29619d2aSchristos        $contents =~ s:$pattern:repstr($pattern, $highlights{$pattern}, $1, $2
318*29619d2aSchristos, $3, $4):gse;
319*29619d2aSchristos    }
320*29619d2aSchristos    foreach $line (split "\n", $contents) {
321*29619d2aSchristos        if ($line eq ""){
322*29619d2aSchristos            print $lineprefix, $blankline;
323*29619d2aSchristos        } else {
324*29619d2aSchristos            print $lineprefix, $line;
325*29619d2aSchristos        }
326*29619d2aSchristos        print "\n";
327*29619d2aSchristos    }
328*29619d2aSchristos}
329*29619d2aSchristos
330*29619d2aSchristossub just_highlight {
331*29619d2aSchristos    my $contents = join "\n", @_;
332*29619d2aSchristos    my $line;
333*29619d2aSchristos    my $ret = "";
334*29619d2aSchristos
335*29619d2aSchristos    foreach $pattern (keys %highlights) {
336*29619d2aSchristos#       print "scanning pattern $pattern ($highlights{$pattern})\n";
337*29619d2aSchristos        $contents =~ s:$pattern:repstr($pattern, $highlights{$pattern}, $1, $2
338*29619d2aSchristos, $3, $4):gse;
339*29619d2aSchristos    }
340*29619d2aSchristos    foreach $line (split "\n", $contents) {
341*29619d2aSchristos        if ($line eq ""){
342*29619d2aSchristos            $ret = $ret . $lineprefix . $blankline;
343*29619d2aSchristos        } else {
344*29619d2aSchristos            $ret = $ret . $lineprefix . $line;
345*29619d2aSchristos        }
346*29619d2aSchristos        $ret = $ret . "\n";
347*29619d2aSchristos    }
348*29619d2aSchristos
349*29619d2aSchristos    return $ret;
350*29619d2aSchristos}
351*29619d2aSchristos
352*29619d2aSchristos# output in texinfo
353*29619d2aSchristossub output_texinfo {
354*29619d2aSchristos    my %args = %{$_[0]};
355*29619d2aSchristos    my ($parameter, $section);
356*29619d2aSchristos    my $count;
357*29619d2aSchristos
358*29619d2aSchristos    print "\@deftypefun {" . $args{'functiontype'} . "} ";
359*29619d2aSchristos    print "{".$args{'function'}."} ";
360*29619d2aSchristos    print "(";
361*29619d2aSchristos    $count = 0;
362*29619d2aSchristos    foreach $parameter (@{$args{'parameterlist'}}) {
363*29619d2aSchristos        print $args{'parametertypes'}{$parameter}." \@var{".$parameter."}";
364*29619d2aSchristos        if ($count != $#{$args{'parameterlist'}}) {
365*29619d2aSchristos            $count++;
366*29619d2aSchristos            print ", ";
367*29619d2aSchristos        }
368*29619d2aSchristos    }
369*29619d2aSchristos    print ")\n";
370*29619d2aSchristos    foreach $parameter (@{$args{'parameterlist'}}) {
371*29619d2aSchristos        if ($args{'parameters'}{$parameter}) {
372*29619d2aSchristos            print "\@var{".$parameter."}: ";
373*29619d2aSchristos            output_highlight($args{'parameters'}{$parameter});
374*29619d2aSchristos            print "\n";
375*29619d2aSchristos        }
376*29619d2aSchristos    }
377*29619d2aSchristos    foreach $section (@{$args{'sectionlist'}}) {
378*29619d2aSchristos        print "\n\@strong{$section:} " if $section ne $section_default;
379*29619d2aSchristos        $args{'sections'}{$section} =~ s:([{}]):\@\1:gs;
380*29619d2aSchristos        output_highlight($args{'sections'}{$section});
381*29619d2aSchristos    }
382*29619d2aSchristos    print "\@end deftypefun\n\n";
383*29619d2aSchristos}
384*29619d2aSchristos
385*29619d2aSchristos# output in html
386*29619d2aSchristossub output_html {
387*29619d2aSchristos    my %args = %{$_[0]};
388*29619d2aSchristos    my ($parameter, $section);
389*29619d2aSchristos    my $count;
390*29619d2aSchristos    print "\n\n<a name=\"". $args{'function'} . "\">&nbsp</a><h2>Function</h2>
391*29619d2aSchristos\n";
392*29619d2aSchristos
393*29619d2aSchristos    print "<i>".$args{'functiontype'}."</i>\n";
394*29619d2aSchristos    print "<b>".$args{'function'}."</b>\n";
395*29619d2aSchristos    print "(";
396*29619d2aSchristos    $count = 0;
397*29619d2aSchristos    foreach $parameter (@{$args{'parameterlist'}}) {
398*29619d2aSchristos        print "<i>".$args{'parametertypes'}{$parameter}."</i> <b>".$parameter.
399*29619d2aSchristos"</b>\n";
400*29619d2aSchristos        if ($count != $#{$args{'parameterlist'}}) {
401*29619d2aSchristos            $count++;
402*29619d2aSchristos            print ", ";
403*29619d2aSchristos        }
404*29619d2aSchristos    }
405*29619d2aSchristos    print ")\n";
406*29619d2aSchristos
407*29619d2aSchristos    print "<h3>Arguments</h3>\n";
408*29619d2aSchristos    print "<dl>\n";
409*29619d2aSchristos    foreach $parameter (@{$args{'parameterlist'}}) {
410*29619d2aSchristos        print "<dt><i>".$args{'parametertypes'}{$parameter}."</i> <b>".$parame
411*29619d2aSchristoster."</b>\n";
412*29619d2aSchristos        print "<dd>";
413*29619d2aSchristos        output_highlight($args{'parameters'}{$parameter});
414*29619d2aSchristos    }
415*29619d2aSchristos    print "</dl>\n";
416*29619d2aSchristos    foreach $section (@{$args{'sectionlist'}}) {
417*29619d2aSchristos        print "<h3>$section</h3>\n";
418*29619d2aSchristos        print "<ul>\n";
419*29619d2aSchristos        output_highlight($args{'sections'}{$section});
420*29619d2aSchristos        print "</ul>\n";
421*29619d2aSchristos    }
422*29619d2aSchristos    print "<hr>\n";
423*29619d2aSchristos}
424*29619d2aSchristos
425*29619d2aSchristos# output in tex
426*29619d2aSchristossub output_tex {
427*29619d2aSchristos    my %args = %{$_[0]};
428*29619d2aSchristos    my ($parameter, $section);
429*29619d2aSchristos    my $count;
430*29619d2aSchristos    my $func = $args{'function'};
431*29619d2aSchristos    my $param;
432*29619d2aSchristos    my $param2;
433*29619d2aSchristos    my $sec;
434*29619d2aSchristos    my $check;
435*29619d2aSchristos    my $type;
436*29619d2aSchristos
437*29619d2aSchristos    $func =~ s/_/\\_/g;
438*29619d2aSchristos
439*29619d2aSchristos    print "\n\n\\subsection{". $func . "}\n\\label{" . $args{'function'} . "}\
440*29619d2aSchristosn";
441*29619d2aSchristos
442*29619d2aSchristos    $type = $args{'functiontype'};
443*29619d2aSchristos    $type =~ s/_/\\_/g;
444*29619d2aSchristos
445*29619d2aSchristos    print "{\\it ".$type."}\n";
446*29619d2aSchristos    print "{\\bf ".$func."}\n";
447*29619d2aSchristos    print "(";
448*29619d2aSchristos    $count = 0;
449*29619d2aSchristos    foreach $parameter (@{$args{'parameterlist'}}) {
450*29619d2aSchristos        $param = $args{'parametertypes'}{$parameter};
451*29619d2aSchristos        $param2 = $parameter;
452*29619d2aSchristos        $param =~ s/_/\\_/g;
453*29619d2aSchristos        $param2 =~ s/_/\\_/g;
454*29619d2aSchristos
455*29619d2aSchristos        print "{\\it ".$param."} {\\bf ".$param2."}";
456*29619d2aSchristos        if ($count != $#{$args{'parameterlist'}}) {
457*29619d2aSchristos            $count++;
458*29619d2aSchristos            print ", ";
459*29619d2aSchristos        }
460*29619d2aSchristos    }
461*29619d2aSchristos    print ")\n";
462*29619d2aSchristos
463*29619d2aSchristos    print "\n{\\large{Arguments}}\n";
464*29619d2aSchristos
465*29619d2aSchristos    print "\\begin{itemize}\n";
466*29619d2aSchristos    $check=0;
467*29619d2aSchristos    foreach $parameter (@{$args{'parameterlist'}}) {
468*29619d2aSchristos        $param1 = $args{'parametertypes'}{$parameter};
469*29619d2aSchristos        $param1 =~ s/_/\\_/g;
470*29619d2aSchristos        $param2 = $parameter;
471*29619d2aSchristos        $param2 =~ s/_/\\_/g;
472*29619d2aSchristos
473*29619d2aSchristos        $check = 1;
474*29619d2aSchristos        print "\\item {\\it ".$param1."} {\\bf ".$param2."}: \n";
475*29619d2aSchristos#       print "\n";
476*29619d2aSchristos
477*29619d2aSchristos        $param3 = $args{'parameters'}{$parameter};
478*29619d2aSchristos        $param3 =~ s/&([a-zA-Z\_]+)/{\\it \1}/g;
479*29619d2aSchristos
480*29619d2aSchristos        $out = just_highlight($param3);
481*29619d2aSchristos        $out =~ s/_/\\_/g;
482*29619d2aSchristos        print $out;
483*29619d2aSchristos    }
484*29619d2aSchristos    if ($check==0) {
485*29619d2aSchristos        print "\\item void\n";
486*29619d2aSchristos    }
487*29619d2aSchristos    print "\\end{itemize}\n";
488*29619d2aSchristos
489*29619d2aSchristos    foreach $section (@{$args{'sectionlist'}}) {
490*29619d2aSchristos        $sec = $section;
491*29619d2aSchristos        $sec =~ s/_/\\_/g;
492*29619d2aSchristos        $sec =~ s/&([a-zA-Z\_]+)/{\\it \1}/g;
493*29619d2aSchristos
494*29619d2aSchristos        print "\n{\\large{$sec}}\\\\\n";
495*29619d2aSchristos        print "\\begin{rmfamily}\n";
496*29619d2aSchristos
497*29619d2aSchristos        $sec = $args{'sections'}{$section};
498*29619d2aSchristos        $sec =~ s/\\:/:/g;
499*29619d2aSchristos        $sec =~ s/&([a-zA-Z\_]+)/{\\it \1}/g;
500*29619d2aSchristos        $sec =~ s/->/\$\\rightarrow\$/g;
501*29619d2aSchristos        $sec =~ s/([0-9]+)\^([0-9]+)/\$\{\1\}\^\{\2\}\$/g;
502*29619d2aSchristos
503*29619d2aSchristos        $out = just_highlight($sec);
504*29619d2aSchristos        $out =~ s/_/\\_/g;
505*29619d2aSchristos
506*29619d2aSchristos        print $out;
507*29619d2aSchristos        print "\\end{rmfamily}\n";
508*29619d2aSchristos    }
509*29619d2aSchristos    print "\n";
510*29619d2aSchristos}
511*29619d2aSchristos
512*29619d2aSchristos
513*29619d2aSchristos# output in sgml DocBook
514*29619d2aSchristossub output_sgml {
515*29619d2aSchristos    my %args = %{$_[0]};
516*29619d2aSchristos    my ($parameter, $section);
517*29619d2aSchristos    my $count;
518*29619d2aSchristos    my $id;
519*29619d2aSchristos
520*29619d2aSchristos    $id = $args{'module'}."-".$args{'function'};
521*29619d2aSchristos    $id =~ s/[^A-Za-z0-9]/-/g;
522*29619d2aSchristos
523*29619d2aSchristos    print "<refentry>\n";
524*29619d2aSchristos    print "<refmeta>\n";
525*29619d2aSchristos    print "<refentrytitle><phrase id=\"$id\">".$args{'function'}."</phrase></r
526*29619d2aSchristosefentrytitle>\n";
527*29619d2aSchristos    print "</refmeta>\n";
528*29619d2aSchristos    print "<refnamediv>\n";
529*29619d2aSchristos    print " <refname>".$args{'function'}."</refname>\n";
530*29619d2aSchristos    print " <refpurpose>\n";
531*29619d2aSchristos    print "  ".$args{'purpose'}."\n";
532*29619d2aSchristos    print " </refpurpose>\n";
533*29619d2aSchristos    print "</refnamediv>\n";
534*29619d2aSchristos
535*29619d2aSchristos    print "<refsynopsisdiv>\n";
536*29619d2aSchristos    print " <title>Synopsis</title>\n";
537*29619d2aSchristos    print "  <funcsynopsis>\n";
538*29619d2aSchristos    print "   <funcdef>".$args{'functiontype'}." ";
539*29619d2aSchristos    print "<function>".$args{'function'}." ";
540*29619d2aSchristos    print "</function></funcdef>\n";
541*29619d2aSchristos
542*29619d2aSchristos#    print "<refsect1>\n";
543*29619d2aSchristos#    print " <title>Synopsis</title>\n";
544*29619d2aSchristos#    print "  <funcsynopsis>\n";
545*29619d2aSchristos#    print "   <funcdef>".$args{'functiontype'}." ";
546*29619d2aSchristos#    print "<function>".$args{'function'}." ";
547*29619d2aSchristos#    print "</function></funcdef>\n";
548*29619d2aSchristos
549*29619d2aSchristos    $count = 0;
550*29619d2aSchristos    if ($#{$args{'parameterlist'}} >= 0) {
551*29619d2aSchristos        foreach $parameter (@{$args{'parameterlist'}}) {
552*29619d2aSchristos            print "   <paramdef>".$args{'parametertypes'}{$parameter};
553*29619d2aSchristos            print " <parameter>$parameter</parameter></paramdef>\n";
554*29619d2aSchristos        }
555*29619d2aSchristos    } else {
556*29619d2aSchristos        print "  <void>\n";
557*29619d2aSchristos    }
558*29619d2aSchristos    print "  </funcsynopsis>\n";
559*29619d2aSchristos    print "</refsynopsisdiv>\n";
560*29619d2aSchristos#    print "</refsect1>\n";
561*29619d2aSchristos
562*29619d2aSchristos    # print parameters
563*29619d2aSchristos    print "<refsect1>\n <title>Arguments</title>\n";
564*29619d2aSchristos#    print "<para>\nArguments\n";
565*29619d2aSchristos    if ($#{$args{'parameterlist'}} >= 0) {
566*29619d2aSchristos        print " <variablelist>\n";
567*29619d2aSchristos        foreach $parameter (@{$args{'parameterlist'}}) {
568*29619d2aSchristos            print "  <varlistentry>\n   <term><parameter>$parameter</parameter
569*29619d2aSchristos></term>\n";
570*29619d2aSchristos            print "   <listitem>\n    <para>\n";
571*29619d2aSchristos            $lineprefix="     ";
572*29619d2aSchristos            output_highlight($args{'parameters'}{$parameter});
573*29619d2aSchristos            print "    </para>\n   </listitem>\n  </varlistentry>\n";
574*29619d2aSchristos        }
575*29619d2aSchristos        print " </variablelist>\n";
576*29619d2aSchristos    } else {
577*29619d2aSchristos        print " <para>\n  None\n </para>\n";
578*29619d2aSchristos    }
579*29619d2aSchristos    print "</refsect1>\n";
580*29619d2aSchristos
581*29619d2aSchristos    # print out each section
582*29619d2aSchristos    $lineprefix="   ";
583*29619d2aSchristos    foreach $section (@{$args{'sectionlist'}}) {
584*29619d2aSchristos        print "<refsect1>\n <title>$section</title>\n <para>\n";
585*29619d2aSchristos#       print "<para>\n$section\n";
586*29619d2aSchristos        if ($section =~ m/EXAMPLE/i) {
587*29619d2aSchristos            print "<example><para>\n";
588*29619d2aSchristos        }
589*29619d2aSchristos        output_highlight($args{'sections'}{$section});
590*29619d2aSchristos#       print "</para>";
591*29619d2aSchristos        if ($section =~ m/EXAMPLE/i) {
592*29619d2aSchristos            print "</para></example>\n";
593*29619d2aSchristos        }
594*29619d2aSchristos        print " </para>\n</refsect1>\n";
595*29619d2aSchristos    }
596*29619d2aSchristos
597*29619d2aSchristos    print "\n\n";
598*29619d2aSchristos}
599*29619d2aSchristos
600*29619d2aSchristos##
601*29619d2aSchristos# output in man
602*29619d2aSchristossub output_man {
603*29619d2aSchristos    my %args = %{$_[0]};
604*29619d2aSchristos    my ($parameter, $section);
605*29619d2aSchristos    my $count;
606*29619d2aSchristos
607*29619d2aSchristos    print ".TH \"$args{'function'}\" 3 \"$args{'sourceversion'}\" \"". $args{'
608*29619d2aSchristosmodule'} . "\" \"". $args{'module'} . "\"\n";
609*29619d2aSchristos
610*29619d2aSchristos    print ".SH NAME\n";
611*29619d2aSchristos
612*29619d2aSchristos    print $args{'function'}."\n";
613*29619d2aSchristos
614*29619d2aSchristos    print ".SH SYNOPSIS\n";
615*29619d2aSchristos    print ".B #include <". lc((split /_/, $args{'function'})[0]) . ".h>\n"
616*29619d2aSchristos        if $args{'includefuncprefix'};
617*29619d2aSchristos    print ".sp\n";
618*29619d2aSchristos    print ".BI \"".$args{'functiontype'}." ".$args{'function'}."(";
619*29619d2aSchristos    $count = 0;
620*29619d2aSchristos    foreach $parameter (@{$args{'parameterlist'}}) {
621*29619d2aSchristos        print $args{'parametertypes'}{$parameter}." \" ".$parameter." \"";
622*29619d2aSchristos        if ($count != $#{$args{'parameterlist'}}) {
623*29619d2aSchristos            $count++;
624*29619d2aSchristos            print ", ";
625*29619d2aSchristos        }
626*29619d2aSchristos    }
627*29619d2aSchristos    print ");\"\n";
628*29619d2aSchristos
629*29619d2aSchristos    print ".SH ARGUMENTS\n";
630*29619d2aSchristos    foreach $parameter (@{$args{'parameterlist'}}) {
631*29619d2aSchristos        print ".IP \"".$args{'parametertypes'}{$parameter}." ".$parameter."\"
632*29619d2aSchristos12\n";
633*29619d2aSchristos        output_highlight($args{'parameters'}{$parameter});
634*29619d2aSchristos    }
635*29619d2aSchristos    foreach $section (@{$args{'sectionlist'}}) {
636*29619d2aSchristos        print ".SH \"" . uc($section) . "\"\n";
637*29619d2aSchristos        output_highlight($args{'sections'}{$section});
638*29619d2aSchristos    }
639*29619d2aSchristos
640*29619d2aSchristos    if ($args{'bugsto'}) {
641*29619d2aSchristos        print ".SH \"REPORTING BUGS\"\n";
642*29619d2aSchristos        print "Report bugs to <". $args{'bugsto'} . ">.\n";
643*29619d2aSchristos    }
644*29619d2aSchristos
645*29619d2aSchristos    if ($args{'copyright'}) {
646*29619d2aSchristos        print ".SH COPYRIGHT\n";
647*29619d2aSchristos        print "Copyright \\(co ". $args{'copyright'} . ".\n";
648*29619d2aSchristos        if ($args{'verbatimcopying'}) {
649*29619d2aSchristos            print ".br\n";
650*29619d2aSchristos            print "Permission is granted to make and distribute verbatim copie
651*29619d2aSchristoss of this\n";
652*29619d2aSchristos            print "manual provided the copyright notice and this permission no
653*29619d2aSchristostice are\n";
654*29619d2aSchristos            print "preserved on all copies.\n";
655*29619d2aSchristos        }
656*29619d2aSchristos    }
657*29619d2aSchristos
658*29619d2aSchristos    if ($args{'seeinfo'}) {
659*29619d2aSchristos        print ".SH \"SEE ALSO\"\n";
660*29619d2aSchristos        print "The full documentation for\n";
661*29619d2aSchristos        print ".B " . $args{'module'} . "\n";
662*29619d2aSchristos        print "is maintained as a Texinfo manual.  If the\n";
663*29619d2aSchristos        print ".B info\n";
664*29619d2aSchristos        print "and\n";
665*29619d2aSchristos        print ".B " . $args{'module'} . "\n";
666*29619d2aSchristos        print "programs are properly installed at your site, the command\n";
667*29619d2aSchristos        print ".IP\n";
668*29619d2aSchristos        print ".B info " . $args{'seeinfo'} . "\n";
669*29619d2aSchristos        print ".PP\n";
670*29619d2aSchristos        print "should give you access to the complete manual.\n";
671*29619d2aSchristos    }
672*29619d2aSchristos}
673*29619d2aSchristos
674*29619d2aSchristossub output_listfunc {
675*29619d2aSchristos    my %args = %{$_[0]};
676*29619d2aSchristos    print $args{'function'} . "\n";
677*29619d2aSchristos}
678*29619d2aSchristos
679*29619d2aSchristos##
680*29619d2aSchristos# output in text
681*29619d2aSchristossub output_text {
682*29619d2aSchristos    my %args = %{$_[0]};
683*29619d2aSchristos    my ($parameter, $section);
684*29619d2aSchristos
685*29619d2aSchristos    print "Function = ".$args{'function'}."\n";
686*29619d2aSchristos    print "  return type: ".$args{'functiontype'}."\n\n";
687*29619d2aSchristos    foreach $parameter (@{$args{'parameterlist'}}) {
688*29619d2aSchristos        print " ".$args{'parametertypes'}{$parameter}." ".$parameter."\n";
689*29619d2aSchristos        print "    -> ".$args{'parameters'}{$parameter}."\n";
690*29619d2aSchristos    }
691*29619d2aSchristos    foreach $section (@{$args{'sectionlist'}}) {
692*29619d2aSchristos        print " $section:\n";
693*29619d2aSchristos        print "    -> ";
694*29619d2aSchristos        output_highlight($args{'sections'}{$section});
695*29619d2aSchristos    }
696*29619d2aSchristos}
697*29619d2aSchristos
698*29619d2aSchristos##
699*29619d2aSchristos# generic output function - calls the right one based
700*29619d2aSchristos# on current output mode.
701*29619d2aSchristossub output_function {
702*29619d2aSchristos#    output_html(@_);
703*29619d2aSchristos    eval "output_".$output_mode."(\@_);";
704*29619d2aSchristos}
705*29619d2aSchristos
706*29619d2aSchristos
707*29619d2aSchristos##
708*29619d2aSchristos# takes a function prototype and spits out all the details
709*29619d2aSchristos# stored in the global arrays/hsahes.
710*29619d2aSchristossub dump_function {
711*29619d2aSchristos    my $prototype = shift @_;
712*29619d2aSchristos
713*29619d2aSchristos    if ($prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ ||
714*29619d2aSchristos        $prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ ||
715*29619d2aSchristos        $prototype =~ m/^(\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ ||
716*29619d2aSchristos        $prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/ ||
717*29619d2aSchristos        $prototype =~ m/^(\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\)]*)\)/)
718*29619d2aSchristos  {
719*29619d2aSchristos        $return_type = $1;
720*29619d2aSchristos        $function_name = $2;
721*29619d2aSchristos        $args = $3;
722*29619d2aSchristos
723*29619d2aSchristos#       print STDERR "ARGS = '$args'\n";
724*29619d2aSchristos
725*29619d2aSchristos        foreach $arg (split ',', $args) {
726*29619d2aSchristos            # strip leading/trailing spaces
727*29619d2aSchristos            $arg =~ s/^\s*//;
728*29619d2aSchristos            $arg =~ s/\s*$//;
729*29619d2aSchristos#           print STDERR "SCAN ARG: '$arg'\n";
730*29619d2aSchristos            @args = split('\s', $arg);
731*29619d2aSchristos
732*29619d2aSchristos#           print STDERR " -> @args\n";
733*29619d2aSchristos            $param = pop @args;
734*29619d2aSchristos#           print STDERR " -> @args\n";
735*29619d2aSchristos            if ($param =~ m/^(\*+)(.*)/) {
736*29619d2aSchristos                $param = $2;
737*29619d2aSchristos                push @args, $1;
738*29619d2aSchristos            }
739*29619d2aSchristos            if ($param =~ m/^(.*)(\[\])$/) {
740*29619d2aSchristos                $param = $1;
741*29619d2aSchristos                push @args, $2;
742*29619d2aSchristos            }
743*29619d2aSchristos#           print STDERR " :> @args\n";
744*29619d2aSchristos            $type = join " ", @args;
745*29619d2aSchristos
746*29619d2aSchristos            if ($parameters{$param} eq "" && $param != "void") {
747*29619d2aSchristos                $parameters{$param} = "-- undescribed --";
748*29619d2aSchristos                print STDERR "Warning($lineno): Function parameter '$param' no
749*29619d2aSchristost described in '$function_name'\n";
750*29619d2aSchristos            }
751*29619d2aSchristos
752*29619d2aSchristos            push @parameterlist, $param;
753*29619d2aSchristos            $parametertypes{$param} = $type;
754*29619d2aSchristos
755*29619d2aSchristos#           print STDERR "param = '$param', type = '$type'\n";
756*29619d2aSchristos        }
757*29619d2aSchristos    } else {
758*29619d2aSchristos        print STDERR "Error($lineno): cannot understand prototype: '$prototype
759*29619d2aSchristos'\n";
760*29619d2aSchristos        return;
761*29619d2aSchristos    }
762*29619d2aSchristos
763*29619d2aSchristos    if ($function_only==0 || defined($function_table{$function_name})) {
764*29619d2aSchristos        output_function({'function' => $function_name,
765*29619d2aSchristos                         'module' => $modulename,
766*29619d2aSchristos                         'sourceversion' => $sourceversion,
767*29619d2aSchristos                         'includefuncprefix' => $includefuncprefix,
768*29619d2aSchristos                         'bugsto' => $bugsto,
769*29619d2aSchristos                         'copyright' => $copyright,
770*29619d2aSchristos                         'verbatimcopying' => $verbatimcopying,
771*29619d2aSchristos                         'seeinfo' => $seeinfo,
772*29619d2aSchristos                         'functiontype' => $return_type,
773*29619d2aSchristos                         'parameterlist' => \@parameterlist,
774*29619d2aSchristos                         'parameters' => \%parameters,
775*29619d2aSchristos                         'parametertypes' => \%parametertypes,
776*29619d2aSchristos                         'sectionlist' => \@sectionlist,
777*29619d2aSchristos                         'sections' => \%sections,
778*29619d2aSchristos                         'purpose' => $function_purpose
779*29619d2aSchristos                         });
780*29619d2aSchristos    }
781*29619d2aSchristos}
782*29619d2aSchristos
783*29619d2aSchristos######################################################################
784*29619d2aSchristos# main
785*29619d2aSchristos# states
786*29619d2aSchristos# 0 - normal code
787*29619d2aSchristos# 1 - looking for function name
788*29619d2aSchristos# 2 - scanning field start.
789*29619d2aSchristos# 3 - scanning prototype.
790*29619d2aSchristos$state = 0;
791*29619d2aSchristos$section = "";
792*29619d2aSchristos
793*29619d2aSchristos$doc_special = "\@\%\$\&";
794*29619d2aSchristos
795*29619d2aSchristos$doc_start = "^/\\*\\*\$";
796*29619d2aSchristos$doc_end = "\\*/";
797*29619d2aSchristos$doc_com = "\\s*\\*\\s*";
798*29619d2aSchristos$doc_func = $doc_com."(\\w+):?";
799*29619d2aSchristos$doc_sect = $doc_com."([".$doc_special."[:upper:]][\\w ]+):(.*)";
800*29619d2aSchristos$doc_content = $doc_com."(.*)";
801*29619d2aSchristos
802*29619d2aSchristos%constants = ();
803*29619d2aSchristos%parameters = ();
804*29619d2aSchristos@parameterlist = ();
805*29619d2aSchristos%sections = ();
806*29619d2aSchristos@sectionlist = ();
807*29619d2aSchristos
808*29619d2aSchristos$contents = "";
809*29619d2aSchristos$section_default = "Description";       # default section
810*29619d2aSchristos$section = $section_default;
811*29619d2aSchristos
812*29619d2aSchristos$lineno = 0;
813*29619d2aSchristosforeach $file (@ARGV) {
814*29619d2aSchristos    if (!open(IN,"<$file")) {
815*29619d2aSchristos        print STDERR "Error: Cannot open file $file\n";
816*29619d2aSchristos        next;
817*29619d2aSchristos    }
818*29619d2aSchristos    while (<IN>) {
819*29619d2aSchristos        $lineno++;
820*29619d2aSchristos
821*29619d2aSchristos        if ($state == 0) {
822*29619d2aSchristos            if (/$doc_start/o) {
823*29619d2aSchristos                $state = 1;             # next line is always the function nam
824*29619d2aSchristose
825*29619d2aSchristos            }
826*29619d2aSchristos        } elsif ($state == 1) { # this line is the function name (always)
827*29619d2aSchristos            if (/$doc_func/o) {
828*29619d2aSchristos                $function = $1;
829*29619d2aSchristos                $state = 2;
830*29619d2aSchristos                if (/-(.*)/) {
831*29619d2aSchristos                    $function_purpose = $1;
832*29619d2aSchristos                } else {
833*29619d2aSchristos                    $function_purpose = "";
834*29619d2aSchristos                }
835*29619d2aSchristos                if ($verbose) {
836*29619d2aSchristos                    print STDERR "Info($lineno): Scanning doc for $function\n"
837*29619d2aSchristos;
838*29619d2aSchristos                }
839*29619d2aSchristos            } else {
840*29619d2aSchristos                print STDERR "WARN($lineno): Cannot understand $_ on line $lin
841*29619d2aSchristoseno",
842*29619d2aSchristos                " - I thought it was a doc line\n";
843*29619d2aSchristos                $state = 0;
844*29619d2aSchristos            }
845*29619d2aSchristos        } elsif ($state == 2) { # look for head: lines, and include content
846*29619d2aSchristos            if (/$doc_sect/o) {
847*29619d2aSchristos                $newsection = $1;
848*29619d2aSchristos                $newcontents = $2;
849*29619d2aSchristos
850*29619d2aSchristos                if ($contents ne "") {
851*29619d2aSchristos                    dump_section($section, $contents);
852*29619d2aSchristos                    $section = $section_default;
853*29619d2aSchristos                }
854*29619d2aSchristos
855*29619d2aSchristos                $contents = $newcontents;
856*29619d2aSchristos                if ($contents ne "") {
857*29619d2aSchristos                    $contents .= "\n";
858*29619d2aSchristos                }
859*29619d2aSchristos                $section = $newsection;
860*29619d2aSchristos            } elsif (/$doc_end/) {
861*29619d2aSchristos
862*29619d2aSchristos                if ($contents ne "") {
863*29619d2aSchristos                    dump_section($section, $contents);
864*29619d2aSchristos                    $section = $section_default;
865*29619d2aSchristos                    $contents = "";
866*29619d2aSchristos                }
867*29619d2aSchristos
868*29619d2aSchristos#           print STDERR "end of doc comment, looking for prototype\n";
869*29619d2aSchristos                $prototype = "";
870*29619d2aSchristos                $state = 3;
871*29619d2aSchristos            } elsif (/$doc_content/) {
872*29619d2aSchristos                # miguel-style comment kludge, look for blank lines after
873*29619d2aSchristos                # @parameter line to signify start of description
874*29619d2aSchristos                if ($1 eq "" && $section =~ m/^@/) {
875*29619d2aSchristos                    dump_section($section, $contents);
876*29619d2aSchristos                    $section = $section_default;
877*29619d2aSchristos                    $contents = "";
878*29619d2aSchristos                } else {
879*29619d2aSchristos                    $contents .= $1."\n";
880*29619d2aSchristos                }
881*29619d2aSchristos            } else {
882*29619d2aSchristos                # i dont know - bad line?  ignore.
883*29619d2aSchristos                print STDERR "WARNING($lineno): bad line: $_";
884*29619d2aSchristos            }
885*29619d2aSchristos        } elsif ($state == 3) { # scanning for function { (end of prototype)
886*29619d2aSchristos            if (m#\s*/\*\s+MACDOC\s*#io) {
887*29619d2aSchristos              # do nothing
888*29619d2aSchristos            }
889*29619d2aSchristos            elsif (/([^\{]*)/) {
890*29619d2aSchristos                $prototype .= $1;
891*29619d2aSchristos            }
892*29619d2aSchristos            if (/\{/) {
893*29619d2aSchristos                $prototype =~ s@/\*.*?\*/@@gos; # strip comments.
894*29619d2aSchristos                $prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
895*29619d2aSchristos                $prototype =~ s@^ +@@gos; # strip leading spaces
896*29619d2aSchristos                dump_function($prototype);
897*29619d2aSchristos
898*29619d2aSchristos                $function = "";
899*29619d2aSchristos                %constants = ();
900*29619d2aSchristos                %parameters = ();
901*29619d2aSchristos                %parametertypes = ();
902*29619d2aSchristos                @parameterlist = ();
903*29619d2aSchristos                %sections = ();
904*29619d2aSchristos                @sectionlist = ();
905*29619d2aSchristos                $prototype = "";
906*29619d2aSchristos
907*29619d2aSchristos                $state = 0;
908*29619d2aSchristos            }
909*29619d2aSchristos        }
910*29619d2aSchristos    }
911*29619d2aSchristos}
912*29619d2aSchristos
913*29619d2aSchristos
914*29619d2aSchristos
915