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