Annotation of embedaddon/bird2/doc/kernel-doc, revision 1.1.1.1
1.1 misho 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 or a type
80: # '@parameter' - name of a parameter
81: # '%CONST' - name of a constant.
82: # '|code|' - literal string
83:
84: # match expressions used to find embedded type information
85: $type_constant = "\\\%(\\w+)";
86: $type_func = "(\\w+\\(\\))";
87: $type_param = "\\\@(\\w+)";
88: $type_struct = "\\\&(\\w+)";
89: $type_env = "(\\\$\\w+)";
90: $type_code = "\\|([^|]*)\\|";
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:
119: # bird documentation
120: %highlights_bird = ( $type_constant, "<const/\$1/",
121: $type_func, "<func/\$1/",
122: $type_struct, "<struct/\$1/",
123: $type_param, "<param/\$1/",
124: $type_code, "<tt>\$1</tt>");
125: $blankline_bird = "<p>";
126:
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:
142: sub 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
151: if ($#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;
161: while ($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;
183: } elsif ($cmd eq "-bird") {
184: $output_mode = "bird";
185: %highlights = %highlights_bird;
186: $blankline = $blankline_bird;
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 = "";
208: foreach $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: #
216: sub 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:
246: sub 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
264: sub 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'}}) {
292: print "<h1>$section</h1>\n";
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
302: sub output_intro_html {
303: my %args = %{$_[0]};
304: my ($parameter, $section);
305: my $count;
306:
307: foreach $section (@{$args{'sectionlist'}}) {
308: print "<h1>$section</h1>\n";
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
319: sub 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
404: sub 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
433: sub 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:
525: # output in birddoc
526: sub output_bird {
527: my %args = %{$_[0]};
528: my ($parameter, $section);
529: my $count;
530: print "<function><p><type>".$args{'functiontype'}."</type>\n";
531: print "<funcdef>".$args{'function'}."</funcdef>\n";
532: print "(";
533: $count = 0;
534: my $ntyped = 0;
535: foreach $parameter (@{$args{'parameterlist'}}) {
536: if ($args{'parametertypes'}{$parameter} ne "") {
537: print "<type>".$args{'parametertypes'}{$parameter}."</type> ";
538: $ntyped++;
539: }
540: print "<param>".$parameter."</param>";
541: if ($count != $#{$args{'parameterlist'}}) {
542: $count++;
543: print ", ";
544: }
545: }
546: print ")";
547: if ($args{'purpose'} ne "") {
548: print " -- ";
549: output_highlight($args{'purpose'});
550: }
551: print "\n";
552:
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";
561: }
562: foreach $section (@{$args{'sectionlist'}}) {
563: print "<funcsect>$section\n";
564: print "<p>\n";
565: output_highlight($args{'sections'}{$section});
566: }
567: print "</function>\n";
568: }
569:
570: # output in birddoc
571: sub 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'}}) {
583: print "<sect>$section\n<p>\n";
584: output_highlight($args{'sections'}{$section});
585: }
586:
587: print "\n\n";
588: }
589:
590: ##
591: # output in man
592: sub 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:
625: sub 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
640: sub 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:
657: sub 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.
671: sub 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.
679: sub 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.
688: sub 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;
798: foreach $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 "") {
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: }
848:
849: $contents = $newcontents;
850: if ($contents ne "") {
851: $contents .= "\n";
852: }
853: $section = $newsection;
854: } elsif (/$doc_end/) {
855:
856: if ($contents ne "") {
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: }
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/^@/) {
872: # $contents =~ s/\&/\\\\\\amp;/g;
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/) {
912: # $contents =~ s/\&/\\\\\\amp;/g;
913: $contents =~ s/\</\\\\\\lt;/g;
914: $contents =~ s/\>/\\\\\\gt;/g;
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: {
935: # $contents =~ s/\&/\\\\\\amp;/g;
936: $contents =~ s/\</\\\\\\lt;/g;
937: $contents =~ s/\>/\\\\\\gt;/g;
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: {
956: $contents .= "\n";
957: }
958: else
959: {
960: $contents .= $1 . "\n";
961: }
962: }
963: }
964: }
965: }
966:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>