File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / bird / doc / kernel-doc
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Aug 22 12:33:54 2017 UTC (6 years, 10 months ago) by misho
Branches: bird, MAIN
CVS tags: v1_6_8p3, v1_6_3p0, v1_6_3, HEAD
bird 1.6.3

    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>