#!/usr/bin/perl
# xref - Build a cross-reference index file for the specified packages. 

use strict;

die "Usage: xref <source file> <output file> ...\n" unless ($#ARGV >= 1);

# Process command line arguments and set options
my $source = shift  @ARGV;
my $outfile = shift @ARGV;
my %xref = ();

process($source);
result($outfile);


sub result
  {
  my $outfile = shift;
  my $old = '';
  my $num = '';
  my $key = '';
  my $first = 0;
  my @numlist = ();

  open(OUT, ">$outfile") || die "Failed to create $outfile: $!";
  print OUT qq~
  <HTML>
  <HEAD>
   <TITLE>Cross Reference Index</TITLE>
  </HEAD>
  <BODY>
  <H1>Cross Reference Index</H1>
  <DL>
  ~;

  foreach $key (sort keys %xref)
    {
    print OUT "\n<DT>$key<DD>\n";
    @numlist = split(/\s/, $xref{$key});
    $old = ''; $first = 1;
    foreach $num (sort {$a <=> $b} @numlist)
      {
      if ($num ne $old)
        { 
        $old = $num; 
        if ($first) { print OUT "$num"; $first = 0; }
        else { print OUT ", $num"; } 
        }
      }
    }
  print OUT qq~

  </DL>
  </BODY>
  </HTML>
  ~;
  close OUT;
  }

sub process
  {
  my $source = shift;
  my $line = '';
  my @match = ();
  my @words = ();
  my $word = '';
  my $lineno = 0;
  my $insidecomment = 0;

  open(SRC, $source) || die "Failed to open $source: $!\n";
  while ($line = <SRC>)
    {
    chomp($line);
    $lineno++;
    # Remove trailing spaces
    $line =~ s/\s*$//;
    # Special treatment of '$#': $#var --> $var
    $line =~ s/\$\#/\$/g;
    # Process single line perl comments
    $line =~ s/\#.*$//;
    # Process single line php/c++ comments
    $line =~ s|//.*$||;
    # Process end and start of multi line comments
    if ($insidecomment)
      {
      if ($line =~ m|\*/|) 
        { $insidecomment = 0; }
      next;
      }
    if ($line =~ m|/\*|)
      {
      $insidecomment = 1 unless (m|/\*.*\*/|);
      next;
      }
    # Process double quoted strings
    while (@match = $line =~ m|([^\"]*)(\"[^\"]*\")(.*)|)
      { $line = $match[0] . $match[2]; }
    # Process single quoted strings
    while (@match = $line =~ m|([^\']*)(\'[^\']*\')(.*)|)
      { $line = $match[0] . $match[2]; }
    # remove all unneeded characters
    $line =~ s/[^\$\%\@\#A-Za-z0-9]/ /g;
    # replace multiple spaces by one space
    $line =~ s/ +/ /g;
    # remove leading space
    $line =~ s/^\s*//;
    # something left?
    next unless ($line);
    # generate wordlist
    @words = split(/\s/, $line);
    foreach $word (@words)
      { $xref{$word} .= $lineno . " "  if ($word =~ /^[\$\%\@\#A-Za-z]/); }
    }
  close SRC;
  }

