#!/usr/bin/perl # # # Copyright (C) 1997-2005, R3vis Corporation. # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 # USA, or visit http://www.gnu.org/copyleft/lgpl.html. # # Original Contributor: # Wes Bethel, R3vis Corporation, Marin County, California # Additional Contributor(s): # # The OpenRM project is located at http://openrm.sourceforge.net/. # # # usage: source2html cSourceFname outputIndexHTMLFile outputHTMLfile # # purpose: # autogenerate HTML documentation from source files by extracting # author-supplied information (comments) from the file marked by # special tags. # # $Id: source2html.pl,v 1.3 2005/02/19 16:47:58 wes Exp $ # Version: $Name: OpenRM-1-6-0-RC5 $ # $Revision: 1.3 $ # $Log: source2html.pl,v $ # Revision 1.3 2005/02/19 16:47:58 wes # Distro sync and consolidation. # # Revision 1.2 2004/01/17 04:04:18 wes # Updated copyright line for 2004. # # Revision 1.1.1.1 2003/01/28 02:15:23 wes # Manual rebuild of rm150 repository. # # Revision 1.2 2000/04/20 16:15:59 wes # JDB modifications. # # Revision 1.1.1.1 2000/02/28 21:29:40 wes # OpenRM 1.2 Checkin # # Revision 1.1.1.1 2000/02/28 17:18:48 wes # Initial entry - pre-RM120 release, source base for OpenRM 1.2. # # # # usage: source2html cSourceFname cLibrary outputIndexHTMLFile outputHTMLfile # # purpose: # autogenerate HTML documentation from source files by extracting # author-supplied information (comments) from the file marked by # special tags. # # # documentation tags $nameTag="\@Name"; $docStartTag="\@dstart"; $docEndTag="\@dend"; $protoStartTag="\@pstart"; $protoEndTag="\@pend"; $argsStartTag="\@astart"; $argsEndTag="\@aend"; # variables $sourceLibrary = "empty"; $sourceFName = "empty"; $sourceFD = "empty"; $destFName = "empty"; $destIndexFD = "empty"; $destContentFD = "empty"; $destContentFName = "empty"; $destContentLink = "empty"; $currentRoutineName = "empty"; sub doLivesInString { # add source file location info print destContentFD "lib", $sourceLibrary, " library source file: ", $sourceFName, "
\n"; } sub doPreamble { # # output simple HTML header # print destContentFD "\n"; print destContentFD "OpenRM - ", uc($sourceLibrary), " Library (", $sourceFName, ")\n"; print destContentFD "\n\n"; print destContentFD "\n
\n
\n"; print destContentFD "\n"; print destContentFD "

Index of OpenRM - ", uc($sourceLibrary), " Library

\n"; print destContentFD "\n"; } sub doEpilogue { # # output a simple HTML footer # print destContentFD ""; } sub doDatatype { # if we're here, then we have a public datatype to document. # public datatypes are distinguished as being defined as follows: # # typedef (struct) RM* # # public datatypes are documented via a copy of their definition # @fields = split(/\s+/, $line); # setup the hyperlink in the index file foreach $i (@fields) { if ($i =~ /RM*/) { print destIndexFD $sourceLibrary, " $i
  • ", $i, " \n"; print destContentFD "", $i, "\n"; break; } } # dump the datatype definition into content file print destContentFD "
    \n";
        while (!($line =~ /\}/))
        {
    	print destContentFD $line;
    	$line = ;
        }
        print destContentFD $line;
        print destContentFD "
    \n"; doLivesInString(); print destContentFD "
    \n"; } sub doName { # # if we're here, then a line containing $nameTag was encountered. # the input line read from $sourceFD is split so that we can pull the name out # the format of the documentation in the source file looks like: # # @Name , so once we find @Name the function name is next # # the split-out name is saved for error reporting in $currentRoutineName # in the event that the tag-pairs are not as expected # @fields = split (/\s+/, $line); my $j = 0; foreach $i (@fields) { if ($i =~ /$nameTag/i) { $currentRoutineName = $fields[$j + 1]; dumpNameTag($fields[$j + 1]); break; } $j++; } } sub dumpNameTag { # # input is a string containing the routine name, passed in from doName() # this just writes out the temp file, with the first two entries being # the library name and the function name, used for sorting out the docs # print destIndexFD $sourceLibrary, " @_
  • ", @_, " \n"; print destContentFD " \n"; } sub doProto { # # if we're here, then a line containing $protoStartTag was encountered. # first, we read in the next line - that means that we throw away # the line containing $protoEndTag. # $line = ; # while the input line DOES NOT contain the $docEndTag, continue reading input and dumping it out. print destContentFD "
    \n";
    
        while (!($line =~ /$protoEndTag/i))
        {
    	print destContentFD $line;
    	$line = ;
    
    	if (eof(sourceFD))
    	{
    	    print "in routine ", $currentRoutineName, " the ", $protoEndTag, " appears to be missing\n";
    	    die; 
    	}
        }
        print destContentFD "
    \n"; } sub doArgs { # # if we're here, then a line containing $argsStartTag was encountered. # first, we read in the next line - that means that we throw away # the line containing $argsEndTag. # $line = ; # while the input line DOES NOT contain the $docEndTag, continue reading input and dumping it out. print destContentFD "
    \n";
    
        while (!($line =~ /$argsEndTag/i))
        {
    	print destContentFD $line;
    	$line = ;
    
    	if (eof(sourceFD))
    	{
    	    print "in routine ", $currentRoutineName, " the ", $argsEndTag, " appears to be missing\n";
    	    die; 
    	}
        }
        print destContentFD "
    \n"; } sub doDoc { # # if we're here, then a line containing $docStartTag was encountered. # first, we read in the next line - that means that we throw away # the line containing $docStartTag. # my $inParagraph = 0; my $wordCount = 0; $line = ; # # while the input line DOES NOT contain the $docEndTag, continue # reading input and dumping it out. # # as this particular script is generating HTML, it looks for # "paragraph boundaries." a paragraph boundary is defined as one or # more blank lines. a

    pair is generated on paragraph boundaries. # # start a paragraph, and eat any blank lines prior to processing. print destContentFD "

    \n"; @fields = split (/\s+/, $line); $wordCount = scalar(@fields); while ($wordCount == 0) { $line = ; @fields = split (/\s+/, $line); $wordCount = scalar(@fields); } # we enter the loop inside a paragraph and with a non-zero $wordCount. while (!($line =~ /$docEndTag/i)) { @fields = split (/\s+/, $line); $wordCount = scalar(@fields); if ($wordCount == 0) { while ($wordCount == 0) { $line = ; @fields = split (/\s+/, $line); $wordCount = scalar(@fields); } if (!($line =~ /$docEndTag/i)) { print destContentFD "

    \n"; print destContentFD "

    \n"; } } else { print destContentFD $line; $line = ; } if (eof(sourceFD)) { print "in routine ", $currentRoutineName, " the ", $docEndTag, " appears to be missing\n"; die; } } print destContentFD "

    \n"; doLivesInString(); } # begin of main() { my $funcInfo = 0, my $dataInfo = 0; # open the source file open (sourceFD, "< $ARGV[0]") or die "ERROR: cannot open the input file."; $sourceFName = $ARGV[0]; # derive the library and determine how deep library is in the RM tree @fields = split(/\//, $ARGV[1]); $sourceLibrary = $fields[$#fields]; # open the output index and content files $destFName = ("../" x $#fields) . "doc/HTML/" . $ARGV[2]; $destContentFName = ("../" x $#fields) . "doc/HTML/" . $ARGV[3]; $destContentLink = "./" . $ARGV[3]; open (destIndexFD, ">>$destFName") or die "ERROR: cannot open the output index file."; open (destContentFD, ">$destContentFName") or die "ERROR: cannot open the output content file."; # do a quick pass to check for signs of documentation while ($line = ) { if (($line =~ /typedef/) && ($line =~ / RM/) && (!($line =~ PRIVATE))) { $dataInfo++; } if ($line =~ /$nameTag/i) { $funcInfo++; } } # if documentation exists then generate an HTML document for the file if ($dataInfo + $funcInfo) { doPreamble(); # do a pass to get any datatype documentation if ($dataInfo) { seek(sourceFD, 0, 0) or die "ERROR: cannot rewind input file for datatype documentation collection."; while ($line = ) { if (($line =~ /typedef/) && ($line =~ / RM/) && (!($line =~ PRIVATE))) # check for typedefs with RM prefixed name { doDatatype($line); } } } # do a pass to get any function documentation if ($funcInfo) { seek(sourceFD, 0, 0) or die "ERROR: cannot rewind input file for function documentation collection."; while ($line = ) { if ($line =~ /$nameTag/i) { doName($line); } if ($line =~ /$docStartTag/i) { doDoc(); } if ($line =~ /$protoStartTag/i) { doProto(); } if ($line =~ /$argsStartTag/i) { doArgs(); } } } doEpilogue(); close(destIndexFD); close(destContentFD); } else # nuke the bogus HTML file if empty { close(destIndexFD); close(destContentFD); if (-z $destContentFName) { system("\\rm $destContentFName"); } } } # EOF