#! /usr/bin/perl -w
# Copyright (C) 2006  Benoit Sigoure <tsuna@lrde.epita.fr>.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
# USA.

use strict; # Oh yeah, spank me baby!
use File::Basename;

# Let's try -in vain- to get non-buffered output.

my $old_select = select STDOUT;
$| = 1;       # Don't buffer output.
select STDERR;
$| = 1;
select $old_select;

if ($#ARGV < 0)
{
  print STDERR "Usage: $0 [-c] prognam [args]\n";
  print STDERR "The -c argument is ignored (compatibility with sh -c).\n";
  exit 1;
}

shift if $ARGV[0] eq '-c';


my $orig_cmd = "@ARGV";

# correct_args(progname, replacement-list)
# If $ARGV[0] is progname or matches progname, it is replaced by
# replacement-list.
sub correct_args($@)
{
  my ($progname, @replacement) = @_;
  if ($ARGV[0] eq $progname)
  {
    shift(@ARGV);
    unshift(@ARGV, @replacement);
    return 1;
  }
  elsif ($ARGV[0] =~ / *$progname +/)
  {
    $ARGV[0] =~ s/ *$progname +//;
    unshift(@ARGV, @replacement);
    return 1;
  }
  return 0;
}

# unixify(string)
# Returns the string with the backslashes transformed in slashes where
# necessary. Some lines are commented for debugging.
sub unixify($)
{
  my $orig = shift;
  my @str = split(//, $orig);
  my $dst = '';
  my $c = 'x';
  my $n = $#str;

  #print "Orig string<$n>: $orig\n";
  for (my $i = 0; $i <= $n; ++$i)
  {
    $c = $str[$i];
    if ($c eq '\'')
    {
      #print "String start: $i\n";
      $dst .= $c;
      ++$i;
      while ($i <= $n && $str[$i] ne "'")
      {
        #print ">String[$i]: $str[$i]\n";
        $dst .= $str[$i++];
      }
      $dst .= '\'' if $i <= $n;
      #print "String end: $i\n";
    }
    else
    {
      if ($c eq '\\')
      {
        if ($str[$i + 1] =~ /[\\'"$ `|*&?]/)
        {
          #print "Char[$i, ", $i + 1, "]: \\$str[$i + 1]\n";
          $dst .= '\\' . $str[++$i];
        }
        else
        {
          $dst .= '/';
          #print "Char[$i]: \\ -> /\n";
        }
      }
      else
      {
        #print "Char[$i]: $c\n";
        $dst .= $c;
      }
    }
  }
  return $dst;
}

# $(SHELL) was invoked (eg, for libtool) forward the call to sh:
correct_args('.*perl.*' . basename($0), 'sh');

# Transform windows utils in UNIX utils:
correct_args('del', 'rm', '-f');
correct_args('byacc', 'bison');
correct_args('copy /y', 'cp', '-f', '-p');
correct_args('xcopy /s /q /y /i', 'cp', '-r', '-f', '-p');
correct_args('move', 'mv', '-f');
correct_args('if not exist', 'test', '-d') && map s/mkdir/|| mkdir/, @ARGV;

# Final step:
my $cmd = unixify("@ARGV");

if ($cmd ne $orig_cmd)
{
  #print STDOUT "$0: Original command: $orig_cmd\n";
  print STDOUT "$0: Rewrote the command to: $cmd\n";
}
exec $cmd or exit $!;
