~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/scripts/kernel-doc

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.