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