summaryrefslogblamecommitdiffstats
path: root/doc/tools/src2html1.4a/src2html
blob: 98d9d83d7f3e7e2f1b3699db47d79ac7c5a330a9 (plain) (tree)
1
2
3
4
5
6
7
8
9
               







                                                                               

       






















                                                                             












                                         





























































































































                                                                                 
                                                                                                      




















                                                                             


                  




                                                                                
                      
                                                                  


                                                                

                                                                   


                                                                

                                                        


                                                                

                                                       


                                                                

                                                         


                                                                

                                                      


                                                                

                                                          


                                                                

                                                          





















































                                                                          






                                                              

                                                                
















                                                                             



                                                                            
















                                                                              




                                                                         
                                                            
                                                         



































                                                                             






                                                                             













                                                                   

                                                                                







































                                                                         





                                                                              









                                     




                                                 









                                





                                      

























                                                                      

                                                                                



































                                                                           




                                                                                  































                                                                           

                                                                                















                                                                       




                                               







































                                                                              
                                                             
                                                              


                                              
                                                               
                                      









                                                                               
                                
































                                                                                 
                                                               



                                        
#!/usr/bin/perl
# Src2html: Take a source tree and generate Html documents that have hyperlinks
# to the definition of structures, variables, functions, and preprocessor
# definitions. Read the manual page for details on how to use the program.
#
# Version 1.4-alpha. Written by Warren Toomey wkt@cs.adfa.oz.au
#
# 19th January 1996
#
#  $Id$
#

if ($#ARGV <= 0 || $#ARGV > 4) {		# Check arg count
    print(STDERR "Usage: $0 [-na] [-nl] [-d num] input_description\n");
    print(STDERR "           -na: Don't produce top-level category files\n");
    print(STDERR "           -nl: Don't produce per-letter files\n");
    print(STDERR "            -d: Set debugging to given number (0-3)\n");
    exit(1);
}

# Set up default option values
$NoLetters= 0;
$NoAll= 0;
$Debug=0;
$Top= $ARGV[$#ARGV];
$Top=~ s/\.s2h$//;

# Parse the options
for ($i=0; $i<= $#ARGV; $i++) {
	if ($ARGV[$i] eq "-na") { $NoAll= 1; next; }
	if ($ARGV[$i] eq "-nl") { $NoLetters= 1; next; }
	if ($ARGV[$i] eq "-d") { $i++; $Debug= $ARGV[$i]; next; }
}

$Title{"m"}= "C Macros";
$Title{"d"}= "C Defines";
$Title{"f"}= "C Functions";
$Title{"v"}= "C Variables";
$Title{"s"}= "C Structs";
$Title{"u"}= "C Unions";
$Title{"t"}= "C Typedefs";
$Title{"e"}= "C Enums";
$Title{"AdaType"}= "Ada Types";
$Title{"AdaProcedure"}= "Ada Procedures";
$Title{"AdaFunction"}= "Ada Functions";
$Title{"AdaPackage"}= "Ada Packages";
$Title{"AdaTask"}= "Ada Tasks";
$Title{"g"}= "All symbols";

&get_s2h;				# Read the description file
&make_dirs;				# Make directories as needed
&make_ctags;				# Generate ctags for all src
&parse_ctags;				# Parse ctags, generate html ptr files
foreach $i (keys(%Dirinfo))
{ &rewrite_src($i); }			# Rewrite the src code
exit(0);				# and exit
 

## get_s2h: Opens the source description file, reads it, and sets up some
## variables describing where some directories are, and the source directories
## to process. Variables used are:
## Srctree - The root of the source tree we are processing
## Htmlroot - The directory where all WWW documents are kept
## Htmldir -  The directory under Htmlroot for this source tree
## Htmltree - The root of the destination tree for the Html code
## Newsrctree - The directory in Htmltree to store the new Htmlised code
## Headers - The directory where we keep information to prepend in some docs
## Formdir - The place to put the index searching script
## Dirinfo{} - The list of dirs and the info about the directory
## Dotdir{} - The directory name with /'s -> .'s

sub get_s2h {
    $Newsrctree= 'newsrc';			# Set up as default
    $Headers= '.';


    #########################################################
    # make sure we dump out the last bit of the last file....

			# Print out the remainder of the
			# current file, incl. the buffered line
    if ($In_file == 1) {
      if ("$line" ne "") { print OUT $line; }
      while (<IN>) {
	      s/\&/&amp;/g; s/\</&lt;/g; s/\>/&gt;/g; print OUT;
	} 
      print OUT "\n\n\n\n\n\n\n\n</pre></body>\n";
      close(IN); close(OUT);
    }
    #########################################################

    open(S2H,$ARGV[$#ARGV])				# Open descript
	|| die "$0: can't open $ARGV[$#ARGV]: $!\n";

    while(<S2H>) {				# Read in input lines
	next if /^#/;				# Skip comments
	if ( /^set\s+Srctree\s+(\S+)/ ) {
	    $Srctree = $1; next;		# Set the variable
	}
	if ( /^set\s+Htmlroot\s+(\S+)/ ) {
	    $Htmlroot = $1; next;		# Set the variable
	}
	if ( /^set\s+Htmldir\s+(\S+)/ ) {
	    $Htmldir = $1; next;		# Set the variable
	}
	if ( /^set\s+Newsrctree\s+(\S+)/ ) {
	    $Newsrctree = $1; next;		# Set the variable
	}
	if ( /^set\s+Headers\s+(\S+)/ ) {
	    $Headers = $1; next;		# Set the variable
	}
	if ( /^set\s+Formdir\s+(\S+)/ ) {
	    $Formdir = $1; next;		# Set the variable
	}
	if ( /^dir\s+(\S+)\s+(.*)/ ) {
	    $Dirinfo{$1}= $2; $Dotdir{$1}=$1;
	    $Dotdir{$1}=~ s/\//./g;
	    next;				# Get dir commands
	}
	if ( /^\n/ ) { next; }			# Ignore blank lines
						# Bad input line, give warning
	chop; print "$_: Bad line, ignoring\n"; next;
    }
    close(S2H);
    if (!defined($Srctree)) { die "$0: Srctree undefined in $ARGV[$#ARGV]\n"; }
    if (!defined($Htmlroot)) { die "$0: Htmlroot undefined in $ARGV[$#ARGV]\n"; }
    if (!defined($Htmldir)) { die "$0: Htmldir undefined in $ARGV[$#ARGV]\n"; }
    $Htmltree= "$Htmlroot/$Htmldir";
}

## make_dirs: Make the directories need to store the Html documents, and also
## check to make sure that the input directories exist. We depend upon mkdir(1)
## having the -p option to make intermediate directories as needed.

sub make_dirs {
    local($i);

    foreach $i (keys(%Dirinfo)) {	     # Check that the directories exist
	if (! -e "$Srctree/$i") {
	    die "$0: Input dir $Srctree/$i doesn't exist\n";
	}
	if (! -d "$Srctree/$i") {
	    die "$0: Input dir $Srctree/$i is not a directory\n";
	}
    }
    if (! -e "$Htmltree") {
	system("mkdir -p $Htmltree") && die "$0: Can't mkdir $Htmltree\n";
    }
    if (! -e "$Htmltree/$Newsrctree") {
	system("mkdir -p $Htmltree/$Newsrctree")
		&& die "$0: Can't mkdir $Htmltree/$Newsrctree\n";
    }
    if (! -e "$Htmltree/ctags") {
	system("mkdir -p $Htmltree/ctags") && die "$0: Can't mkdir ctags\n";
    }
    foreach $i (keys(%Dirinfo)) {
	if (! -e "$Htmltree/$Newsrctree/$i") {
	    system("mkdir -p $Htmltree/$Newsrctree/$i")
		&& die "$0: Can't mkdir $Htmltree/$Newsrctree/$i\n";
	}
    }
}

## make_ctags: Process all the source code, creating the ctags files.
## The Ctagsfile{} array is set up to hold the name of the ctags files
## created.

sub make_ctags {
    local($i);

    foreach $i (keys(%Dirinfo)) {
	$Ctagsfile{$i}= "$Htmltree/ctags/$Dotdir{$i}.ctags";
	if ($Debug > 0 ) { print "Generating ctags for $Ctagsfile{$i}\n"; }
	system("(cd $Srctree; /usr1/rtems/rtemsdoc-work/tools/src2html/ctags-wr $i) > $Ctagsfile{$i}")
	&& print "$0: ctags failed on $Srctree/$i\n";
    }
}


## parse_ctags: Parse the ctags file produced by make_ctags, creating several
## arrays of information. The arrays created are:
## Macro{} - The name of every macro and its name lowercased
## Def{} - The name of every define and its name lowercased
## Func{} - The name of every function and its name lowercased
## Var{} - The name of every variable and its name lowercased
## Struct{} - The name of every struct and its name lowercased
## Union{} - The name of every union and its name lowercased
## Type{} - The name of every typedef and its name lowercased
## Enum{} - The name of every enum and its name lowercased
## Nfile{} - The directory in which the symbol was found
## Nline{} - The line number where the symbol was found

sub parse_ctags {
    local($i);
    local($low);
    local($count);

    $count = 0;

    foreach $i (keys(%Dirinfo)) {
	open(CTAGS,$Ctagsfile{$i}) || die "$0: Can't open $Ctagsfile{$i}, $!\n";
	if ($Debug > 0) { print "Parsing $Ctagsfile{$i} to build ptr files\n"; }
	while (<CTAGS>) {
            $count ++;
	    if ( /^(\w+)\s+(\d+)\s+(\S+)\s+Preprocessor macro/ ) {
		($low=$1)=~tr/A-Z_/a-z/d;	$k="$low$count";
		$Macro{$k}=$1;			$Nline{$k}= $2;
		$Nfile{$k}= $3;			next;
	    }
	    if ( /^(\w+)\s+(\d+)\s+(\S+)\s+Preprocessor define/ ) {
		($low=$1)=~tr/A-Z_/a-z/d; 	$k="$low$count";
		$Def{$k}=$1;			$Nline{$k}= $2;
		$Nfile{$k}= $3;			next; 
	    }
	    if ( /^(\w+)\s+(\d+)\s+(\S+)\s+C struct/ ) {
		($low=$1)=~tr/A-Z_/a-z/d; 	$k="$low$count";
		$Struct{$k}=$1;			$Nline{$k}= $2;
		$Nfile{$k}= $3;			next;
	    }
	    if ( /^(\w+)\s+(\d+)\s+(\S+)\s+C union/ ) {
		($low=$1)=~tr/A-Z_/a-z/d; 	$k="$low$count";
		$Union{$k}=$1;			$Nline{$k}= $2;
		$Nfile{$k}= $3;			next; 
	    }
	    if ( /^(\w+)\s+(\d+)\s+(\S+)\s+C typedef/ ) {
		($low=$1)=~tr/A-Z_/a-z/d; 	$k="$low$count";
		$Type{$k}=$1;			$Nline{$k}= $2;
		$Nfile{$k}= $3;			next; 
	    }
	    if ( /^(\w+)\s+(\d+)\s+(\S+)\s+C enum/ ) {
		($low=$1)=~tr/A-Z_/a-z/d; 	$k="$low$count";
		$Enum{$k}=$1;			$Nline{$k}= $2;
		$Nfile{$k}= $3;			next;
	    }
	    if ( /^(\w+)\s+(\d+)\s+(\S+)\s+C function/ ) {
		($low=$1)=~tr/A-Z_/a-z/d; 	$k="$low$count";
		$Func{$k}=$1;			$Nline{$k}= $2;
		$Nfile{$k}= $3;			next;
	    }
	    if ( /^(\w+)\s+(\d+)\s+(\S+)\s+C variable/ ) {
		($low=$1)=~tr/A-Z_/a-z/d; 	$k="$low$count";
		$Var{$k}=$1;			$Nline{$k}= $2;
		$Nfile{$k}= $3;			next;
	    }
	    if ( /^(return)\/.\s+(\d+)\s+(\S+)\s+.*/ ) {
                next;
                # Code like the following line results in "return" as ctag
                #    "type Action is access function return Boolean;
            }
	    if ( /^(\w+)\/.\s+(\d+)\s+(\S+)\s+use .*/ ) {
                next;
                # throw away lines like "use type System"
            }

	    if ( /^(\w+)\/.\s+(\d+)\s+(\S+)\s+type .*/ ) {
		($low=$1)=~tr/A-Z_/a-z/d; 	$k="$low$count";
		$AdaType{$k}=$1;		$Nline{$k}= $2;
		$Nfile{$k}= $3;			next;
	    }
	    if ( /^(\w+)\/.+\s+(\d+)\s+(\S+)\s+procedure .*/ ) {
		($low=$1)=~tr/A-Z_/a-z/d; 	$k="$low$count";
                $AdaProcedure{$k}=$1;		$Nline{$k}= $2;
		$Nfile{$k}= $3;			next;
	    }
	    if ( /^(\w+)\/.+\s+(\d+)\s+(\S+)\s+function .*/ ) {
		($low=$1)=~tr/A-Z_/a-z/d; 	$k="$low$count";
		$AdaFunction{$k}=$1;		$Nline{$k}= $2;
		$Nfile{$k}= $3;			next;
	    }
	    if ( /^(\".+)\/.+\s+(\d+)\s+(\S+)\s+function .*/ ) {
                next;
                # throw away functions like "*"
	    }
	    if ( /^(\w+)\/.\s+(\d+)\s+(\S+)\s+package .*/ ) {
		($low=$1)=~tr/A-Z_/a-z/d; 	$k="$low$count";
		$AdaPackage{$k}=$1;		$Nline{$k}= $2;
		$Nfile{$k}= $3;			next;
	    }
	    if ( /^(\w+)\/.\s+(\d+)\s+(\S+)\s+task .*/ ) {
		($low=$1)=~tr/A-Z_/a-z/d; 	$k="$low$count";
		$AdaTask{$k}=$1;		$Nline{$k}= $2;
		$Nfile{$k}= $3; next;
	    }
	    if ( /^([\w\/]+)\s+(\d+)\s+(\S+)\s+use type .*/ ) {
		next;
	    }
	    if ( /^([\w\/\(]+)\s+(\d+)\s+(\S+)\s+type .*/ ) {
		next;
	    }
	    if ( /^;([\w\/\(]+)\s+(\d+)\s+(\S+)\s+type .*/ ) {
		next;
	    }
	    if ( /^\(([\w\/\(]+)\s+(\d+)\s+(\S+)\s+procedure .*/ ) {
		next;
	    }
	    print "$0: In Ctagsfile{$i}, don't recognise $_";
	}
	close(CTAGS);
	&make_dir_html($i);
	undef %Macro; undef %Def; undef %Func; undef %Var;
	undef %Struct; undef %Union; undef %Type; undef %Enum;
	undef %AdaType; undef %AdaProcedure; undef %AdaFunction;
        undef %AdaPackage; undef %AdaTask;
    }
  &make_top_html;
}

## make_letters_html: Make the lowest HTML documents, i.e those per-directory
## per-type per-letter Htmls that point directly at the source code.
## Arguments are:  Dir name, prefix, title, Name/dir list
## If the file is created, set $Exists(letter) positive, else to 0.

sub make_letters_html {
    local($dir)= $_[0];
    local($pref)= $_[1];
    local($title)= $_[2];
    local(*type)= $_[3];
    local($htmlfile);
    local($let)="@";
  
    foreach $i ( "a".."z",
       "AdaType", "AdaProcedure", "AdaFunction", "AdaPackage", "AdaTask" ) {
        $Exists{$i}=0;
    }
    foreach $name (sort keys( %type )) {
	if (substr($name,0,1) ne $let) {
	    if ($let ne "@") {
	        print HTML "</ul></body>\n";
	        close(HTML);
	        $Exists{$let}= 1;
	    }
	    $let= substr($name, 0, 1);
	    $htmlfile= "$Htmltree/$Dotdir{$dir}.$pref$let.html";
	    open(HTML, "> $htmlfile") || die "$0: Can't open $htmlfile, $!\n";
  
	    print HTML "<head>\n<title>$title starting with ";
	    print HTML "`$let' in $dir</title>\n";
	    print HTML "</head><body><h1>$title starting with ";
	    print HTML "`$let' in $dir</h1><p>\n";
	    print HTML "<ul>\n";
	}
        # print HTML "<li><a href=\"$Newsrctree/$Nfile{$type{$name}}";
        # print HTML ".html#$type{$name}\">$type{$name}</a> ";
        # print HTML "$Nfile{$type{$name}}:$Nline{$type{$name}}\n"; next;

        print HTML "<li><a href=\"$Newsrctree/$Nfile{$name}";
        print HTML ".html#$type{$name}\">$type{$name}</a> ";
        print HTML "$Nfile{$name}:$Nline{$name}\n"; next;
    }
    print HTML "</ul></body>\n";
    close(HTML);
    $Exists{$let}= 1;
}

## make_type_html: Make the type htmls. If there are <50 symbols for the
## directory, create the per-directory per-type html document only. Otherwise
## for every letter grep symbols, call make_lowest_letter_html, and
## finally create the per-directory per-type html document that points only
## at the letter files created.
## Arguments are:  Dir name, prefix, title, Name/dir list

sub make_type_html {
    local($dir)= $_[0];
    local($pref)= $_[1];
    local($title)= $_[2];
    local(*type)= $_[3];
    local($i);
    local($htmlfile);
    local(@keys)= keys(%type);
    local($name);

    $Exists{$title}=0;
    if ( $#keys < 0 ) { return; }
    if ($Debug > 0) {
	$i= $#keys + 1;
	print "The associative array for $dir $title has $i elements\n";
    }
    if ( ($#keys < 50) || ($NoLetters == 1) ) {
	$htmlfile= "$Htmltree/$Dotdir{$dir}.$pref.html";
	open(HTML, "> $htmlfile") || die "$0: Can't open $htmlfile, $!\n";
	print HTML "<head>\n<title>$title in $dir</title>\n";
	print HTML "</head><body><h1>$title in $dir</h1>\n";
	print HTML "<ul>\n";
	foreach $name (sort keys( %type )) {
	    # print HTML "<li><a href=\"$Newsrctree/$Nfile{$type{$name}}";
	    # print HTML ".html#$type{$name}\">$type{$name}</a> ";
	    # print HTML "$Nfile{$type{$name}}:$Nline{$type{$name}}\n"; next;

            print HTML "<li><a href=\"$Newsrctree/$Nfile{$name}";
            print HTML ".html#$type{$name}\">$type{$name}</a> ";
            print HTML "$Nfile{$name}:$Nline{$name}\n"; next;
	}
	print HTML "</ul></body>\n";
	close(HTML);
	$Exists{$title}=1;
    }
    else {
	&make_letters_html($dir, $pref, $title, *type);

	open(HTML, "> $Htmltree/$Dotdir{$dir}.$pref.html")
		|| die "$0: Can't open $htmlfile.$pref.html, $!\n";
	print HTML "<head>\n<title>$title in $dir</title>\n";
	print HTML "</head><body><h1>$title in $dir</h1><p>\n";
	print HTML "<ul>\n";
    
	foreach $i ( "a".."z",
           "AdaType", "AdaProcedure", "AdaFunction", "AdaPackage", "AdaTask" ) {
	    if ($Exists{$i} > 0) {			# A file exists
		print HTML "<li><a href=\"$Dotdir{$dir}.$pref$i.html\">";
		print HTML "$i</a>\n"; $Exists{$title}++; $Exists{$i}=0;
	    }
	}
	print HTML "</ul></body>\n";
	close(HTML);
	if ($Exists{$title} == 0) { unlink($htmlfile); }
    }
}

## asappend: Append the contents of the second associative array to the
## first.

sub asappend {
    local(*To)= $_[0];
    local(*From)= $_[1];
    local($i);

    foreach $i (keys(%From)) { $To{$i}= $From{$i} ; }
}

## make_dir_html: Make the html document for the directory. Use the
## Exist{} array to determine what types to include on the document.
## Arguments are:  Dir name

sub make_dir_html {
    local($dir)= $_[0];
    local($i);
    local(@keys);

    if ($Debug > 1) { print"In makedir, dir is $dir\n"; }
    &make_type_html($dir, "f", $Title{"f"}, *Func);
    &make_type_html($dir, "m", $Title{"m"}, *Macro);
    &make_type_html($dir, "d", $Title{"d"}, *Def);
    &make_type_html($dir, "v", $Title{"v"}, *Var);
    &make_type_html($dir, "s", $Title{"s"}, *Struct);
    &make_type_html($dir, "u", $Title{"u"}, *Union);
    &make_type_html($dir, "t", $Title{"t"}, *Type);
    &make_type_html($dir, "e", $Title{"e"}, *Enum);
    &make_type_html($dir, "AdaType", $Title{"AdaType"}, *AdaType);
    &make_type_html($dir,
         "AdaProcedure", $Title{"AdaProcedure"}, *AdaProcedure);
    &make_type_html($dir, "AdaFunction", $Title{"AdaFunction"}, *AdaFunction);
    &make_type_html($dir, "AdaPackage", $Title{"AdaPackage"}, *AdaPackage);
    &make_type_html($dir, "AdaTask", $Title{"AdaTask"}, *AdaTask);

    if ($NoAll != 1) {
        &asappend(*GFunc, *Func);
        &asappend(*GMacro, *Macro);
        &asappend(*GDef, *Def);
        &asappend(*GVar, *Var);
        &asappend(*GStruct, *Struct);
        &asappend(*GUnion, *Union);
        &asappend(*GType, *Type);
        &asappend(*GEnum, *Enum);
        &asappend(*GAdaType, *AdaType);
        &asappend(*GAdaProcedure, *AdaProcedure);
        &asappend(*GAdaFunction, *AdaFunction);
        &asappend(*GAdaPackage, *AdaPackage);
        &asappend(*GAdaTask, *AdaTask);
    }

    &asappend(*Alldir, *Func);
    &asappend(*Alldir, *Macro);
    &asappend(*Alldir, *Def);
    &asappend(*Alldir, *Var);
    &asappend(*Alldir, *Struct);
    &asappend(*Alldir, *Union);
    &asappend(*Alldir, *Type);
    &asappend(*Alldir, *Enum);
    &asappend(*Alldir, *AdaType);
    &asappend(*Alldir, *AdaProcedure);
    &asappend(*Alldir, *AdaFunction);
    &asappend(*Alldir, *AdaPackage);
    &asappend(*Alldir, *AdaTask);

    if ($NoLetters != 1) {
        &make_letters_html($dir, "g", $Title{"g"}, *Alldir);
    }
    undef %Alldir;

    open(HTML, "> $Htmltree/$Dotdir{$dir}.html")
	|| die "$0: Can't open $Htmltree/$Dotdir{$dir}.html, $!\n";
    print HTML "<head>\n<title>Cross-references for $dir</title>\n";
    print HTML "</head><body><h1>Cross-references for $dir</h1><p>\n";
    if (-f "$Headers/$Dotdir{$dir}.hdr" ) {
	open(TOPHDR, "$Headers/$Dotdir{$dir}.hdr");
	while (<TOPHDR>) { print HTML; }
	close(TOPHDR);
    }

    if (defined($Formdir)) {
        print HTML "<hr><form action=\"$Formdir/src2html.cgi\" ";
	print HTML "method=\"POST\">\n";
        print HTML "<input type=\"submit\" value=\"Search\">\n";
        print HTML "<input type= \"text\" ";
	print HTML "name=\"$Htmldir/$Newsrctree\">\n";
        print HTML "Enter a symbol's name here to quickly find it.\n";
        print HTML "</form><hr>\n";
    }
    print HTML "<h1>Cross-references for $dir by type</h1><p><ul>\n";
    
    foreach $i ( "f","m","d","v","s","u","t","e",
           "AdaType", "AdaProcedure", "AdaFunction", "AdaPackage", "AdaTask" ) {
	if ($Exists{$Title{$i}} > 0) {		# A type exists
	    print HTML "<li><a href=\"$Dotdir{$dir}.$i.html\">";
	    print HTML "$Title{$i}</a>\n";
	    $Exists{$dir}++; $Exists{$Title{$i}}=0;
	}
    }
    print HTML "</ul><p>\n";
    if ($NoLetters != 1) {
        print HTML "<h1>Cross-references for $dir by letter</h1><p><ul>\n";
        foreach $i ( "a".."z" ) {
	    if ($Exists{$i} > 0) {			# A letter exists
	        print HTML "<li><a href=\"$Dotdir{$dir}.g$i.html\">";
	        print HTML "$i</a>\n"; $Exists{$i}=0;
	    }
        }
    }
    print HTML "</ul></body>\n";
    close(HTML);
}

## Make_top_html: Make the top html document by making the ones below
## it and then adding links to them.

sub make_top_html {
    local($i);
    local(@keys);

    $Dotdir{$Top}=$Top;
    &make_type_html($Top, "f", $Title{"f"}, *GFunc);
    &make_type_html($Top, "m", $Title{"m"}, *GMacro);
    &make_type_html($Top, "d", $Title{"d"}, *GDef);
    &make_type_html($Top, "v", $Title{"v"}, *GVar);
    &make_type_html($Top, "s", $Title{"s"}, *GStruct);
    &make_type_html($Top, "u", $Title{"u"}, *GUnion);
    &make_type_html($Top, "t", $Title{"t"}, *GType);
    &make_type_html($Top, "e", $Title{"e"}, *GEnum);
    &make_type_html($Top, "AdaType", $Title{"AdaType"}, *GAdaType);
    &make_type_html($Top, "AdaProcedure", $Title{"AdaProcedure"}, *GAdaProcedure);
    &make_type_html($Top, "AdaFunction", $Title{"AdaFunction"}, *GAdaFunction);
    &make_type_html($Top, "AdaPackage", $Title{"AdaPackage"}, *GAdaPackage);
    &make_type_html($Top, "AdaTask", $Title{"AdaTask"}, *GAdaTask);

    open(HTMLTOP, "> $Htmltree/$Top.html")
	|| die "$0: Can't open $Htmltree/$Top.html, $!\n";
    print HTMLTOP "<head>\n<title>Cross-references for $Top</title>\n";
    print HTMLTOP "</head><body><h1>Cross-references for $Top</h1><p>\n";

    if (-f "$Headers/$Top.hdr" ) {
	open(TOPHDR, "$Headers/$Top.hdr");
	while (<TOPHDR>) { print HTMLTOP; }
	close(TOPHDR);
    }

    if (defined($Formdir)) {
        print HTMLTOP "<hr><form action=\"$Formdir/src2html.cgi\" ";
	print HTMLTOP "method=\"POST\">\n";
        print HTMLTOP "<input type=\"submit\" value=\"Search\">\n";
        print HTMLTOP "<input type= \"text\" ";
	print HTMLTOP "name=\"$Htmldir/$Newsrctree\">\n";
        print HTMLTOP "Enter a symbol's name here to quickly find it.\n";
        print HTMLTOP "</form><hr>\n";
    }
    print HTMLTOP "<h2>Cross-references by directory</h2><p>\n";
    print HTMLTOP "<ul>\n";
    
    foreach $i (sort keys(%Dirinfo)) {
	if ($Exists{$i} > 0) {			# A dir exists
	    print HTMLTOP "<li><a href=\"$Dotdir{$i}.html\">";
	    print HTMLTOP "$i</a> $Dirinfo{$i}\n"; $Exists{$i}=0;
	}
    }
    if ($NoAll != 1) {
        print HTMLTOP "</ul><p><h2>Cross-references by type</h2><p><ul>\n";
        foreach $i ( "f","m","d","v","s","u","t","e",
           "AdaType", "AdaProcedure", "AdaFunction", "AdaPackage", "AdaTask" ) {
	    if ($Exists{$Title{$i}} > 0) {		# A type exists
	        print HTMLTOP "<li><a href=\"$Top.$i.html\">";
	        print HTMLTOP "$Title{$i}</a>\n"; 
	    }
        }
        if ($NoLetters != 1) {
            print HTMLTOP "</ul><p><h2>All Cross-references for $Top";
	    print HTMLTOP "</h2><p><ul>\n";
            &asappend(*Alltop, *GFunc);
            &asappend(*Alltop, *GMacro);
            &asappend(*Alltop, *GDef);
            &asappend(*Alltop, *GVar);
            &asappend(*Alltop, *GStruct);
            &asappend(*Alltop, *GUnion);
            &asappend(*Alltop, *GType);
            &asappend(*Alltop, *GEnum);
            &asappend(*Alltop, *GAdaType);
            &asappend(*Alltop, *GAdaProcedure);
            &asappend(*Alltop, *GAdaFunction);
            &asappend(*Alltop, *GAdaPackage);
            &asappend(*Alltop, *GAdaTask);
    
            if ($Debug > 0) { print "Making top letters\n"; }
   	    &make_letters_html($Top, "g", $Title{"g"}, *Alltop);
    	    if ($Debug > 0) { print "Making top letters, part 2\n"; }
    	    foreach $i ( "a".."z" ) {
		    if ($Exists{$i} > 0) {
	    	    print HTMLTOP "<li><a href=\"$Dotdir{$Top}.g$i.html\">";
	    	    print HTMLTOP "$i</a>\n";
		    }
    	    }
        }
    }
    print HTMLTOP "</ul>\n";
    print HTMLTOP "<hr>This source tree was made with ";
    print HTMLTOP "<a href=\"http://minnie.cs.adfa.oz.au/Src2html/index.html";
    print HTMLTOP "\">src2html</a>.</body>\n";
    close(HTMLTOP);
}


## rewrite_src: Reread the ctags file for the given directory, and
## rewrite the source code, adding in anchor points and bolding symbols.
## This is messy as we can have multiple symbols on a single source line,
## therefore we must buffer each line while reading from the ctags file.
##
sub rewrite_src {
    local($dir)= $_[0];
    local($i);
    local($file)="";
    local($line)="";
    local($symb);
    local($cnt);
    local($nextcnt);

    $In_file=0;
    open(CTAGS,"sort +2 -3 +1n -2 $Ctagsfile{$dir} |")
	|| die "$0: Can't open sorted $Ctagsfile{$dir}, $!\n";
    if ($Debug > 0) { print "Rewriting source in $dir\n"; }
    while (<CTAGS>) {
					# Get the next file, line, symbol
	if (/^([\w\/]+)\s+(\d+)\s+([A-Za-z0-9_\+\-\.\/]+)/) {
            if ($Debug > 2) { print "Symb $1 at $2 in $3\n"; }
	    $fname=$3; $nextcnt= $2; $symb=$1;
            $symb=~ s/\/.//g;

					# If it's in a new file
	    if ("$file" ne "$fname") {
					# Print out the remainder of the
					# current file, incl. the buffered line
		if ($In_file == 1) {
		    if ("$line" ne "") { print OUT $line; }
		    while (<IN>) {
	                s/\&/&amp;/g; s/\</&lt;/g; s/\>/&gt;/g; print OUT;
		    }
		    print OUT "\n\n\n\n\n\n\n\n\n\n</pre></body>\n";
		    close(IN); close(OUT);
		}
		$file= "$fname";
					# Open the new file & do the preamble
		open(IN, "$Srctree/$file") ||
		    print "Cannot open $Srctree/$file\n";
		open(OUT, "> $Htmltree/$Newsrctree/$file.html");
		$In_file=1;
		print OUT "<head>\n<title>$file Source</title>\n";
		print OUT "</head><body>\n";
		print OUT "<h1>Source to $file</h1>\n";
		if (defined($Formdir)) {
        	    print OUT "<hr><form action=\"$Formdir/src2html.cgi\" ";
	 	    print OUT "method=\"POST\">\n";
        	    print OUT "<input type=\"submit\" value=\"Search\">\n";
        	    print OUT "<input type= \"text\" ";
		    print OUT "name=\"$Htmldir/$Newsrctree\">\n";
		    print OUT "Enter a symbol's name here to quickly find it.\n";
		    print OUT "</form><hr>\n";
		}
		print OUT "<pre>\n";
					# Get the first line
		$cnt=1; $line = <IN>;
	        $line=~ s/\&/&amp;/g;
	        $line=~ s/\</&lt;/g;
	        $line=~ s/\>/&gt;/g;
	    }
	}
					# Print all lines until one with a symb
	while ($cnt < $nextcnt) {
	    print OUT $line; $cnt++; $line= <IN>;
	    $line=~ s/\&/&amp;/g;
	    $line=~ s/\</&lt;/g;
	    $line=~ s/\>/&gt;/g;
	}
						# Now rewrite the line
	$line=~ s/\b$symb\b/<a name="$symb"<\/a><b>$symb<\/b>/;
	next;
    }
    close(CTAGS); close(IN); close(OUT);
}