#!/usr/local/bin/perl5
# -*-perl-*-

#/*@@
#  @file      grdoc
#  @date      Sun Apr 21 10:50:43 1996
#  @author    Paul Walker
#  @desc 
# grdoc: A Code Documenting system
# <pre>
# Code:          Paul Walker <pwalker@ncsa.uiuc.edu>
# Conception:    Paul Walker, Joan Masso <jmasso@ncsa.uiuc.edu>
# Elisp:         Alan Shutko <ats@wurel.wustl.edu>, Paul Walker
# Documentation: http://jean-luc.ncsa.uiuc.edu/Codes/grdoc/
# </pre>
# Alas, this is a fairly memory intensive process.  If that bothers you,
# sorry!  It also makes probably too many passes over the files, but I
# also don't care about that, since I don't run it too often.  With
# TeX conversion on, this can take a Looong time ...
#  @enddesc 
#  @comment
# $Id: grdoc,v 1.32 1996/04/27 00:04:27 pwalker Exp $
#  @endcomment
#@@*/

#/*@@
#  @routine    main
#  @date       Sun Apr 21 10:51:40 1996
#  @author     Paul Walker
#  @desc 

#  This is the main driver to the grdoc system.  It sets up
#  configuration varialbls (editable below), builds a filelist, and then
#  generates all the html.

#  Note this also creates all the relevant directories etc... and calls 
#  a heck of a lot of subdirs!

#  @enddesc 
#  @calls     strip_dirs, NotYet, tex_init, sub_dir,
#     MakeSrcHTML, grdoc_parse, grdoc_richdoc, html_head, html_foot
#     insert_header, navigation, insert_readme, resolve_XRefs,
#     dir_list_index, make_helppage, routine_listing, file_listing,
#     dir_listing, atAts_db, grdoc_varindex, grdoc_tree, grdoc_printable
#  @comment
#  The output here is probably a bit extensive
#  @endcomment
# @@*/


# User configuration goes here
$installdir = "/afs/ncsa.uiuc.edu/projects/genrel/home/pwalker/Perl/grdoc";
$copyright_to = "University of Illinois Board of Trustees";
$organization = "NCSA Relativity Group";
$defauthor = "webmaster\@jean-luc.ncsa.uiuc.edu";
$find = "/bin/find";

# If you want support for TeX equations in containers, you need to
# correctly set these variables.
$TeX     = "/afs/ncsa/packages/tex/bin.IRIX_5.2/tex";
$Dvips   = "/afs/ncsa/packages/tex/bin.IRIX_5.2/dvips";
# Imagemagick
$Convert = "/afs/ncsa/projects/genrel/systems/IRIX_5.2/bin/convert";

# End of user configuration.  Don't edit below here unless you can 
# distinguish <STDIN> from <STDOUT>

@suffixes = (
	     ".c", ".C", ".f", ".F", ".cpp", ".h", ".inc", ".pro",
	     ".el",
	     );

# Show off!
print <<EOM;
-------------------------------------------------------
grdoc: A Code Documenting System
Paul Walker with Joan Masso
http://jean-luc.ncsa.uiuc.edu/Codes/grdoc/
-------------------------------------------------------


EOM

require 'getopts.pl';
require "$installdir/grdoc_helpers";
require "$installdir/grdoc_converters";
require "$installdir/grdoc_indexers";
require "$installdir/grdoc_richdoc";
require "$installdir/grdoc_parse";
require "$installdir/grdoc_parsedo";
require "$installdir/grdoc_tree";
require "$installdir/grdoc_varindex";
require "$installdir/grdoc_texsupport";
require "$installdir/grdoc_helppage";

# Get input options
&Getopts("f:i:o:a:c:VTO");
$author = $opt_a || $defauthor;

#sanity check
if (!($opt_i || $opt_f) && !$opt_o) {
    print <<EOM;
  USAGE: grdoc [-i indir] [-f filelist] -o outdir -t URL_top
      [-V] [-a author_email] [-c "code name"]
EOM
    exit(123);
}

($opt_f || -d $opt_i) || die "$opt_i is not a directory";
(-d $opt_o) || die "$opt_o is not a directory";
if (! (-d "$opt_o/PROTECTED/")) {
    print "Creating $opt_o/PROTECTED Directory\n";
    mkdir ("$opt_o/PROTECTED/", 0755);
}
$opt_c = "Code from $opt_i" if (!$opt_c);
$opt_t = "GRDOCREPLACEWITHRELATIVEXREF";

# Make sure to remove the trailing / if hey are there
$opt_i =~ s:/$::;
$opt_o =~ s:/$::;
$opt_t =~ s:/$::;

&tex_init() if $opt_T;

#enable multi-line matching
$* = 1;

# Set table element highlighting colors.  Good a place as any, I guess...
$toprowHL = "#ffff76";
$pvrowHL  = "#ffffcc";
$srcrowHL = $pvrowHL;		# For now!
$blahrowHL = "#dddddd";
$lastrowHL = "#ddffdc";

# Start a find or read the filelist
print "-------- grdoc: Building File LIst ------\n";
if (!$opt_f) {
    print "   Starting $find\n";
    open (FIND, "$find $opt_i -print |");
    while (<FIND>) {
	chop;
	$thefile = $_;
	next if m:/(RCS|CVS):;
	if (-d $thefile) {
	    # Handle a directory
	    $dirname = &strip_dirs($thefile);
	    $destdir = $thefile;
	    $destdir =~ s/$opt_i/$opt_o/;
	    if (! -d $destdir) {
		print "===> Creating $destdir\n";
		mkdir($destdir, 0755) || die "mkdir: $!\n";
	    }
	    &NotYet($destdir);
	    $destdir =~ s:$opt_o:$opt_o/PROTECTED:;
	    if (! -d $destdir) {
		print "===> Creating $destdir\n";
		mkdir($destdir, 0755) || die "mkdir: $!\n";
	    }
	    &NotYet($destdir);
	    next;
	} 
	$doit = 0;
	foreach $suffix (@suffixes) {
	    $doit = 1 if $thefile =~ /$suffix$/;
	}
	next if !$doit;
	@filelist = (@filelist, $thefile);
    }
} else {
    # This is a crude first attempt at this functionality...
    open (LISTFILE, "<$opt_f") || die "Can't open $opt_f: $!\n";
    print "   Reading $opt_f\n";
    while (<LISTFILE>) {
	$_ =~ s:\n::g;
	if (-d $thefile) {
	    # Handle a directory
	    $dirname = &strip_dirs($thefile);
	    $destdir = $thefile;
	    $destdir =~ s/$opt_i/$opt_o/;
	    if (! -d $destdir) {
		print "===> Creating $destdir\n";
		mkdir($destdir, 0755) || die "mkdir: $!\n";
	    }
	    &NotYet($destdir);
	    $destdir =~ s:$opt_o:$opt_o/PROTECTED:;
	    if (! -d $destdir) {
		print "===> Creating $destdir\n";
		mkdir($destdir, 0755) || die "mkdir: $!\n";
	    }
	    &NotYet($destdir);
	    next;
	} 
	@filelist = (@filelist, $_);
    }
}

# Pass 1  Unfortunately, we have to do two passes, so we can get the
# see also cross references correct.

print "-------- grdoc: Pass 1 ---------\n";
foreach $thefile (@filelist) {

    $filebase = &strip_dirs($thefile);
    print " --> Pass 1 on $filebase ($thefile)\n" if $opt_V;
    $mysubdir = &sub_dir($thefile);
    $totallines{$filebase} = 0;
    $totalgrdlines{$filebase} = 0;
    push (@allfiles, $filebase);
    $msdidx = $mysubdir;
    $rootfiles{$filebase} = 1 if (!($msdidx =~ m:\S:));
    $dirs{$msdidx} = 1;
    $mysubdir{$filebase} = $msdidx;
    
    open (IN, "< $thefile") || die "$infile: $!\n";
    $gotone = 0;
    $ingrdoc = 0;
    $isfort = 0;
    $isfort = 1 if ($thefile =~ m:\.(f|F|inc)$:);
    while (<IN>) {
	$totallines{$filebase}++;
	$totalgrdlines{$filebase}++ if $ingrdoc;
	if (m:/\*\@\@:) {
	    $ingrdoc = 1;
	    $totalgrdlines{$filebase}++;
	    $gotone = 1;
	    $fmode = 0;
	    $fmode = 1 if (m:c/\*\@\@:i);
	}
	if (m:\@\@\*/:) {
	    $ingrdoc = 0;
	}
	if (m:\@(file|header)\s+(\S+):i) {
	    $file_val = $2;
	    $file_val =~ s:\n: :g;
	    $file_val =~ s: ::g;
	    $file_home{$file_val} = $filebase;
	    print "       FILE: $file_val\n" if $opt_V;
	}
	if (m:\@routine\s+(\S+):i) {
	    $routine_val = $1;
	    $gotmine = 0;
	    $routine_val =~ s:\n: :g;
	    $routine_val =~ s: ::g;
	    $routine_home{$routine_val} = $filebase;
	    print "       ROUTINE: $routine_val\n" if $opt_V;
	}
	if (m:(^\s+subroutine.*)$: && $isfort && !$gotmine) {
	    $doingsub = 1;
	    $gotmine = 1;
	    $routine_f_sub{$routine_val} = $1;
	    print "       SUBDEF  :$1\n" if $opt_V;
	} elsif (m:^(     [^\s].*)$: && $doingsub) { 
	    $routine_f_sub{$routine_val} .= "\n$1";
	    print "       SUBDEF C:$1\n" if $opt_V;
	} else {
	    $doingsub = 0;
	}
    }
    print "       STATS: $totallines{$filebase}, " if $opt_V;
    print "$totalgrdlines{$filebase} doc\n" if $opt_V;
}


print "-------- grdoc: Pass 2 ---------\n";
foreach $thefile (@filelist) {
    $filebase = &strip_dirs($thefile);
    print " --> Pass 2 on $filebase ($thefile)\n" if $opt_V;
    &makeSrcHTML($thefile);
    &grdoc_parse($thefile);
    &grdoc_richdoc($thefile);
}
close FIND;

# OK so pass one is complete.  We can now begin to make the indices.
print "\n\n------------- grdoc: Making Indices ----------------\n";

# First create the main index.html file.  This contains a possible README.html
# insertion and then some choices.
$undercon = "<img src=\"http://jean-luc.ncsa.uiuc.edu/Group/images/TeenyUnderCon.gif\" border=0>";
open (OUT, "> $opt_o/index.html") || die "$opt_o/index.html: $!\n";
&html_head($opt_c);
&insert_header ($opt_i);
&navigation("./");
&insert_readme ($opt_i);
print OUT <<EOM;
<h3>Different File/Routine/Variable Views</h3>
<ul>
<li><a href="Routines.html">View routines alphabetically</a>
<li><a href="Files.html">View files alphabetically</a>
<li><a href="Vars.html">View variables</a>
<li><a href="Pars.html">View parameters</a>
<li><a href="Tree.html">Enter the routine calling tree</a>
EOM
$didsubtree = 0;
foreach $ROUTINE (sort cialph keys %routine_home) {
    if ($routineTreeEntry{$ROUTINE}) {
	if (!$didsubtree) {
	    print OUT " or choose an Entry Point.<ul>\n";
	    $didsubtree = 1;
	}
	$d = $routineTreeEntry{$ROUTINE};
	$d =~ s:GRDOCENTRY::;
	$d =~ s:^\s+::;
	$d =~ s:\s+$::;
	$d = "($d)" if ($d =~ m:\S:);
	$xr = &resolve_XRefs("\@seeroutine $ROUTINE", "norich");
	$xr =~ s:_Doc:_Tree:;
	print OUT "<li>$xr $d\n";
    }
}
print OUT "</ul>\n" if $didsubtree;
print OUT<<EOM;
</ul>

<h3>Subdirectory based File Views</h3>
EOM
&dir_list_index();
print OUT <<EOM;
<h3>Suitable for Printing</h3>
Note: it is not clear that the cross-links in the File and Routine 
printable listing work.  I will fix this one day, but right now, it seems
pretty unimportant.
<ul>
<li><a href="Files_Print.html">A list of all Files and Headers</a>
<li><a href="Routines_Print.html">A list of all Routines</a>
<li><a href="Vars.html">A list of all variables</a>
<li><a href="Pars.html">A list of all parameters</a>
</ul>
<hr>
EOM
&navigation("./");
&html_foot($opt_c);
close OUT;


# OK, make the listings and help page
&make_helppage();
&routine_listing();
&file_listing();
&dir_listing();
&atAts_db();

print "\n-------- grdoc: Trees, Vars, and printables ---------\n";
&grdoc_varindex();
&grdoc_tree();
&grdoc_printable();		# In grdoc_indexers

print "\n-------- grdoc: Creating local refs ---------\n";
print "Creating relative hrefs\n" if $opt_V;
open (FIND, "$find $opt_o -name \"*.html\" -print |");
while (<FIND>) 
{
    chop;
    $pfile = &strip_dirs($_);
    # Use this here, not the (probably broken) &make_dotdot routine.
    $dotdot = $_;
    $dotdot =~ s:/[^/]+$:/:;
    $dotdot =~ s:$opt_o::;

    $dotdot = "" if ($dotdot =~ m:^/$:);
    $dotdot =~ s:/[^/]+:/..:g;
    $dotdot =~ s:^/::;

    open (HTML, "< $_") || die "INTERNAL ERROR: $_ $!\n";
    open (TMP, "> $_.$$");
    while ($hl = <HTML>) {
	$hl =~ s!$opt_t/!$dotdot!g;
	$hl =~ s!\.\.//!\.\./!g;
	print TMP $hl;
    }
    close HTML;
    close TMP;
    system "/bin/mv $_.$$ $_";
}



print <<EOM;

-------------------------------------------------------
grdoc: Execution complete.  Run with -V to get
       context of WARNING messages.
-------------------------------------------------------
EOM

