Annotation of embedaddon/bird/doc/kernel-doc, revision 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>