#!/usr/bin/perl -w
#< patch-conv.pl in-file - convert to unix form
# 2010-05-14 - some further refinements
use strict;
use warnings;
my $pgmname = $0;
if ($pgmname =~ /(\\|\/)/) {
   my @tmparr = split(/(\\|\/)/,$pgmname);
   $pgmname = $tmparr[-1];
}
my $in_file = '';
my $out_file = 'temp2.patch';
my $os = $^O;

sub prt($) {
   print shift;
}

sub write2file($$) {
   my ($txt,$fil) = @_;
   open WOF, ">$fil" or die("ERROR: Unable to create $fil! $!\n");
   binmode WOF if ($os =~ /^MSWin/i);
   print WOF $txt;
   close WOF;
}

# $line = remove_x_param($line) if ($line =~ /^diff\s+/);
sub remove_x_param($) {
    my ($ln) = shift;
    my $len = length($ln);
    my $nln = '';
    my ($i,$nc,$ch,$i2);
    for ($i = 0; $i < $len; $i++) {
        $i2 = $i + 1;
        $ch = substr($ln,$i,1);
        $nc = ($i2 < $len) ? substr($ln,$i2,1) : '';
        if (($ch eq '-')&&($nc eq 'x')) {
            # eat this paramerter
            $i++;
            for ( ; $i < $len; $i++) {
                $ch = substr($ln,$i,1);
                last if ($ch =~ /\s/);
            }
        }
        $nln .= $ch;
    }
    return $nln;
}

sub process_file($) {
   my ($inf) = shift;
   my @narr = ();
   if (! open INF, "<$inf") {
      prt("ERROR: Can NOT open [$inf] file!\n");
      return \@narr;
   }
   my @lines = <INF>;
   close INF;
   my $lncnt = scalar @lines;
   prt("Doing $lncnt lines, from [$inf]...\n");
   my ($line,$cnt,$ecnt);
   $cnt = 0;
   foreach $line (@lines) {
      chomp $line;
      $line =~ s/\r$//;
      next if ($line =~ /^Only\s+in\s+/);
      next if ($line =~ /^Binary\s+files\s+/);
      if (($line =~ /^\+\+\+\s+/)||($line =~ /^---\s+/)||($line =~ /^diff\s+/)) {
         if ($line =~ /\\/) {
            $line =~ s/\\/\//g;
            $cnt++;
            $line = remove_x_param($line) if ($line =~ /^diff\s+/);
         }
      }
      push(@narr,$line);
   }
   $ecnt = scalar @narr;
   prt("Converted $cnt lines, got $ecnt, from $lncnt...\n");
   return \@narr;
}

### MAIN ###
# ================================================
parse_args(@ARGV);
prt("Processing $in_file...\n");
my $ra = process_file($in_file);
write2file(join("\n",@{$ra})."\n",$out_file);
prt("Written to [$out_file]...\n");
prt("run \$ patch [-p1] [--dry-run] -i $out_file\n");
exit(0);
# ================================================

sub give_help {
   prt("$pgmname: version 0.0.1 - Apr 26, 2010\n");
   prt("Usage: $pgmname [options] in_file\n");
   prt("Options:\n");
   prt(" --help  -h (-?)  = This help, and exit 0\n");
   prt(" --out <file> -o  = Set output file, Default=$out_file, in current directory.\n");
   prt("\n");
   prt("Purpose: Read the input file, as a diff -u patch file, and convert\n");
   prt("paths to unix form, and write to output file (default=$out_file)\n");
   prt("hopefully to make the output patch file more suitable for 'patch', like\n");
   prt("\$ patch [-p1] [--dry-run] -i $out_file\n");
   prt("\n");
}

sub need_arg {
   my ($arg,@av) = @_;
   if (!@av) {
      prt("ERROR: Argument $arg requires a following argment.\n");
      exit(1)
   }
}

sub parse_args {
   my (@av) = @_;
   while (@av) {
      my $arg = $av[0];
      if ($arg =~ /^-/) {
         my $sarg = substr($arg,1);
         $sarg = substr($sarg,1) while ($sarg =~ /^-/);
         if (length($sarg)) {
            my $ch = substr($sarg,0,1);
            if (($ch =~ /^h/i) || ($ch eq '?')) {
               give_help();
               exit(0);
            } elsif ($ch =~ /^o/i) {
               need_arg(@av);
               shift @av;
               $sarg = $av[0];
               $out_file = $sarg;
               prt("Set output to $out_file\n");
            } else {
               prt("ERROR: [$arg] is NOT a valid argument! Try -? for help.\n");
               exit(1);
            }

         } else {
            prt("ERROR: [$arg] is NOT a valid argument! Try -?\n");
            exit(1);
         }
      } else {
         if (length($in_file)) {
            prt("ERROR: Only ONE valid input file can be given!\n");
            exit(1);
         }
         $in_file = $arg;
         if (-f $in_file ) {
            prt("Set input to $in_file\n");
         } else {
            prt("ERROR: [$arg] is NOT a valid file! Check name, location.\n");
            exit(1);
         }
      }

      shift @av;
   }
   if ((length($in_file) == 0) || ( ! -f $in_file )) {
      prt("ERROR: Must give a valid input file! Try -?\n");
      exit(1);
   }
}


# eof - patch-conv.pl



