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