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