#!/lusr/bin/perl #---------------------------------------------------------------------------- # Program: class2html (C++ class hierarchy in HTML) # # Version: 0.1 # # Date: Wed Jul 1 00:22:09 CDT 1998 initial version # # Description: # # quick and dirty C++ class hierarchy viewer with # simple colorization. Creates a single HTML file of class # hierarchies with links to colorized source code. # Able to handle multiple header files at once. # # Author: Yoonsuck Choe Copyright (c) 1998 # # Licensing Terms : Freely distributable for private use only (with this # header section intact). # Provided as-is. No warranty. # # Usage: # class2html [...] # # output: stdout -- you can redirect it to a html file and # view it with a graphical browser. # # ex: class2html > class.html # # Source URL: # # http://www.cs.utexas.edu/users/yschoe/src/class2html # # Requirements: # # Perl Version 5.003 or better # * may work with older versions, but I cannot tell for sure. # # Pitfalls, restrictions, and TIPS # # There are certain restrictions on how the c++ header should # be written (however, if you don't do anything weird it would # generally work). # # 1. class [: [public|private|protected [,]]+] { # should be on a single line. # 2. These should be aligned at the beginning of the line. # - The end of class curly brace '};' # - The 'class' keyword # - The 'template' keyword # 3. The colorization is not very context sensitive -- it is # rather a "find pattern and substitute" thing, so don't # expect much. ;-) # # TODO: # 1. Colorization is not intelligent enough. # Closing the parenthesis is the most trouble. ;-) # Especially, it doesn't handle function pointers very well. # #---------------------------------------------------------------------------- #------------------------------ # usage: class2html #------------------------------ $version = "0.1"; if ($#ARGV == -1) { print "usage: class2html \n\t output: standard output\n"; exit 0; } #------------------------------ # print HTML header #------------------------------ print ""; print " class2html v$version <\/title>\n"; print "<center><table border=0 width=500><tr><td bgcolor=\#ffeeee><br><h1 align=center> class2html v$version<\/h1><br><\/td><\/tr><\/table><\/center>\n"; #------------------------------ # load all files (while tagging them) #------------------------------ # print file list and link print "<h3> Files </h3> <ol>\n"; for ($i = 0; $i<=$#ARGV; ++$i) { open(HFILE,"< $ARGV[$i]"); push(@src,"<a name=\"$ARGV[$i]\"><table border=0 width=700><tr><td bgcolor=\#ffeeee><h1>FILE: $ARGV[$i]<\/h1><\/td><\/tr><\/table>\n"); push(@src,<HFILE>); close HFILE; print "<li> <a href=\"\#$ARGV[$i]\">$ARGV[$i]<\/a>"; } print "<\/ol><hr>\n"; #------------------------------ # get class hierarchy #------------------------------ for ($x=0; $x<=$#src; ++$x) { $x = &parse_class_hier($x); } #------------------------------ # print class hierarchy #------------------------------ print "<h3> Class Hierarchy </h3>\n"; print "<ul>\n"; foreach $sup (@root_hier) { if ($sup !~ "class2html_END") { print "<li><a href=\"\#$sup\">$sup<\/a>\n"; if ($deriv_hier{"$sup"}) { &print_sub_class($sup); } } } print "<\/ul>\n"; #------------------------------ # print tagged and colorized source #------------------------------ print "<pre>\n"; $closeit = 0; for ($i=0; $i<= $#src-1; ++$i) { if ($closeit) { if ($src[$i] =~ s/\)/\<font\ color=blue\>\)\<\/font\>/g) { $closeit = 0; } } # colorize keywords $src[$i] =~ s/(public:|private:|protected:)/\<font\ color=blue\>$1\<\/font\>/g; #$src[$i] =~ # s/(virtual)/\<font\ color=green\>$1\<\/font\>/g; $src[$i] =~ s/(\#define)(.+\n)/\<font\ color=\#8888ff\>$1$2\<\/font\>/g; $src[$i] =~ s/(\/\/)(.+\n)/\<font\ color=green>$1$2\<\/font\>/g; $src[$i] =~ s/(^\}\;)/\<font\ color=red\>$1<\/font\>/g; if ($src[$i] =~ s/([~a-zA-Z0-9_]+[\s]*\()/\<font\ color=blue\>$1\<\/font\>/g) { if ($src[$i] =~ s/\)/\<font\ color=blue\>\)\<\/font\>/g) { $closeit = 0; } else { $closeit = 1; } } # take care of < and > if ($src[$i] =~ /(^\#include|^template)/) { $src[$i] =~ s/\</\<\ /g; $src[$i] =~ s/\>/\>/g; } print $src[$i]; } print "<\/pre>\n"; &print_trailer; # THE END #---------------------------------------------------------------------------- # # Parser Subroutines # #---------------------------------------------------------------------------- sub parse_class_hier { local ($i) = @_; $i = &find_next("^class",$i); chop $src[$i]; if ($src[$i] =~ /\;/){ # pre-declaration $i = &find_next("^class",$i); return $i; } # print "[$src[$i]]\n"; if ($src[$i] =~ /:/) { # derived class if ($src[$i] =~ /,/) { # multiple inheritance ($front,$back) = split(/:[\s]+/,$src[$i]); ($junk,$derived) = split(/[\s]+/,$front); ($supstr,$junk) = split(/\{/,$back); @supers = split(/,[\s]+/,$supstr); foreach $typesuper (@supers) { ($type,$super) = split(/[\s]+/,$typesuper); if ($deriv_hier{"$super"}) { $deriv_hier{"$super"} = $deriv_hier{"$super"}.":".$derived; } else { $deriv_hier{"$super"} = $derived; } } } else { # single inheritance ($junk,$derived,$colon,$type,$super,$curl) = split(/[\s]+/,$src[$i]); if ($deriv_hier{"$super"}) { $deriv_hier{"$super"} = $deriv_hier{"$super"}.":".$derived; } else { $deriv_hier{"$super"} = $derived; } } $src[$i] = "<a name=\"$derived\"><font color=red>$src[$i]<\/font>\n"; } else { # stand-alone class if ($src[$i] !~ "class2html_END") { ($junk,$std,$curl) = split(/[\s]+/,$src[$i]); push(@root_hier,$std); $src[$i] = "<a name=\"$std\"><font color=red>$src[$i]<\/font>\n"; } } # print "\n"; return $i; } #---------------------------------------------------------------------------- sub print_sub_class { local ($cur_class) = @_; local ($c); local (@derived); @derived = split(/:/,$deriv_hier{"$cur_class"}); if ($#derived < 0) { return 0; } print "<ol>\n"; foreach $c (@derived) { print "\t<li><a href=\"#$c\">$c<\/a>\n"; &print_sub_class($c); } print "<\/ol>\n"; return 0; } #---------------------------------------------------------------------------- # # Misc Subroutines # #---------------------------------------------------------------------------- sub find_next { local ($str,$line) = @_; while ($src[$line] !~ /$str/) { $line++; if ($line > $#src) { $src[$#src+1] = "class2html_END"; return $#src+1; } } return $line; } #---------------------------------------------------------------------------- sub print_trailer { $srcurl = "http://www.cs.utexas.edu/users/yschoe/src/class2html"; $trailer = "Script written by Yoonsuck Choe". "<<a href=\"mailto:yschoe\@cs.utexas.edu\"> yschoe\@cs.utexas.edu</a>>\n". "<br> <i> Powered by ". "<a href=\"http://www.perl.org\">Perl</a></i>". " (<a href=\"$srcurl\">script source</a>)". "</body></html>"; print "<hr>"; print $trailer; }