#!/usr/bin/env perl
#
# Called with two arguments: The path to $(TOP) and the path to a dep file.
#
# This script fixes up the dep file so that it can be used from anywhere
# in the tree - it makes all file references that are currently relative
# to the value of $(TOP) to instead be relative to the variable $(TOP).
#
# For example, it changes this:
#
#    foo/bar.cmo:  src/baz.cmi
#
# with a TOP of "." to this:
#
#    $(TOP)/foo/bar.cmo:  $(TOP)/src/baz.cmi
#
# To fix limitations in ocamldep, special actions are done if two extra
# paths, A and B, are given.
#
# 1) Any path starting with A is changed to start with B
# 2) Any bare name with no relative path is also changed to start with B

sub trim($)
{
  my($s) = @_;
  $s =~ s|^\s+||;
  $s =~ s|\s+$||;
  return $s;
}

die "Usage: fixdep <TOP> <depfile> [A B]\n" unless ( scalar(@ARGV) == 2 or scalar(@ARGV) == 4 );

my $top = shift @ARGV;
my $dep = shift @ARGV;
my $a   = shift @ARGV;
my $b   = shift @ARGV;

my @newdep;

my $prev = "";

open( DEP, "<", $dep ) or die "Can't read '$dep': $!\n";
while ( <DEP> ) {
  my $line = "$prev$_";
  chomp($line);
  if ( $line =~ m|\\$| ) {
    $prev = $line;
    $prev =~ s|\\$||;
    next;
  }
  $prev = "";
  my ( $left, $right ) = split( ':', $line, 2 );
  my @left = split( /\s+/, trim($left) );
  my @right = split( /\s+/, trim($right) );
  do { s|^\Q$a\E|$b|g foreach ( @left, @right ) } if ( defined $a and defined $b );
  do { m|/| or s|^|$b|g foreach ( @left, @right ) } if ( defined $a and defined $b );
  do { m|^\.| or m|^/| or s|^|./|g foreach ( @left, @right ) };
  s|^\Q$top\E|\$(TOP)|g foreach ( @left, @right );
  push @newdep, sprintf( "%s: %s\n", join( ' ', @left ), join( ' ', @right ) );
}
close( DEP ) or die "Can't close '$dep': $!\n";

open( DEP, ">", $dep ) or die "Can't write '$dep': $!\n";
print DEP @newdep;
close( DEP ) or die "Can't write '$dep': $!\n";

exit(0);
