#Perl to compare lines of VHDL source code
# ignores comments
# ignores white space
# ignores capitalization

$filename1 = shift;
$filename2 = shift;
die "Usage: c:\>vcomp.pl filename1.vhd filename2.vhd\n" unless $filename1 and $filename2;

open(FILE1, "< $filename1") or die "Could not open $filename1 for input $!";
open(FILE2, "< $filename2") or die "Could not open $filename2 for input $!";

while ($line1 = <FILE1>) {
  chomp $line1;
  $line1 = $` if $line1 =~ m/--/;
  $raw1 = $line1;
  $line1 = lc $line1;
  $line1 =~ s/\s+/ /g; 
  $line1 = $' if $line1 =~ m/^\s+/;
  $line1 = $` if $line1 =~ m/\s+$/;
  if ($line1) {
    # extra logic to accumulate stuff until it ends with a ';'
    $e_line1 = $e_line1 . $line1;
    $e_raw1 = $e_raw1 . $raw1;
    if ($line1 =~ m/;$/) {
      push @lines1, $e_line1;
      push @raws1, $e_raw1;
      $e_line1 = '';
      $e_raw1 = '';
    } else {
      $e_line1 = $e_line1 . " ";
      $e_raw1 = $e_raw1 . "\n";
    }
  }
}
close FILE1;
while ($line2 = <FILE2>) {
  chomp $line2;
  $raw2 = $line2;
  $line2 = lc $line2;
  $line2 = $` if $line2 =~ m/--/;
  $line2 =~ s/\s+/ /g; 
  $line2 = $' if $line2 =~ m/^\s+/;
  $line2 = $` if $line2 =~ m/\s+$/;
  if ($line2) {
    # extra logic to accumulate stuff until it ends with a ';'
    $e_line2 = $e_line2 . $line2;
    $e_raw2 = $e_raw2 . $raw2;
    if ($line2 =~ m/;$/) {
      push @lines2, $e_line2;
      push @raws2, $e_raw2;
      $e_line2 = '';
      $e_raw2 = '';
    } else {
      $e_line2 = $e_line2 . " ";
      $e_raw2 = $e_raw2 . "\n";
    }
  }
}
close FILE2;

$num1 = scalar(@lines1);
$num2 = scalar(@lines2);
$num1 < $num2 ? $num = $num1 : $num = $num2;

print "1:$filename1 has $num1 significant lines\n";
print "2:$filename2 has $num2 significant lines\n\n";

$found_difference = 0;
foreach $i (0..$num-1) {
  $line1 = @lines1[$i];
  $line2 = @lines2[$i];
  if ($line1 ne $line2) {
    print "1: $raws1[$i]\n";
    print "2: $raws2[$i]\n\n";
    $found_difference++;
  }
}

if ($num1 > $num) {
  print "$filename1 is longer:\n";
  foreach $i ($num..$num1-1) {
    print "1: $raws1[$i]\n";
    $found_difference++;
  }
}
if ($num2 > $num) {
  print "$filename2 is longer:\n";
  foreach $i ($num..$num2-1) {
    print "2: $raws2[$i]\n";
    $found_difference++;
  }
}
if ($found_difference) {
  print "Found $found_difference significantly different lines.\n" if $found_difference;
} else {
  print "Files appear to be functionally identical.\n";
}