#!/perl -w
# NAME: delsvn.pl
# AIM: To read a diff -u file, and exclude files in .svn folders...
# 8/30/2009 - geoff mclane - http://geoffair.net/mperl/
use strict;
use warnings;
use File::Basename;
unshift(@INC, 'C:/GTools/perl');
require 'logfile.pl' or die "Unable to load logfile.pl ...\n";
# log file stuff
my ($LF);
my $pgmname = $0;
if ($pgmname =~ /\w{1}:\\.*/) {
   my @tmpsp = split(/\\/,$pgmname);
   $pgmname = $tmpsp[-1];
}
my $outfile = "temp.$pgmname.txt";
open_log($outfile);

my $svn_dir = "C:\\FGCVS\\ffmpeg\\"; 
my $in_file = 'C:\Projects\hb\ffmpeg\build\msvc\tempdiff.txt';
my $out_file = 'tempdiff.txt';
my @file_list = ();
my %file_hash = ();
my @warnings = ();

sub prtw($) {
	my ($txt) = shift;
	prt($txt);
	$txt =~ s/\n$//;
	push(@warnings,$txt);
}

sub show_warnings() {
    if (@warnings) {
        prt( "\nGot ".scalar @warnings." WARNINGS ...\n" );
        foreach my $line (@warnings) {
            prt("$line\n" );
        }
    } else {
        prt("\nNo warnings issued.\n");
    }
	#my $s = get_dbg_str();
	#prt( "WARNING: DEBUG ON [$s]\n" ) if length($s);
   prt("\n");
}

sub sub_base_svn_dir($) {
   my ($fil) = shift;
   $fil = substr($fil,length($svn_dir));
   return $fil;
}

sub process_file($) {
   my ($fil) = @_;
   my (@lines, $line, $cnt, $i, $dcnt);
   my (@arr, $ac, $j, $nm, $dir, $ext, $itm);
   my ($mcnt, $fcnt, $msg, $bnm);
   my @nlines = ();
   $dcnt = 0;
   $mcnt = 0;
   if (open INF, "<$fil") {
      @lines = <INF>;
      $cnt = scalar @lines;
      prt( "Processing $cnt lines, from [$fil]...\n" );
      for ($i = 0; $i < $cnt; $i++) {
         $line = $lines[$i];
         chomp $line;
         if ($line =~ /^diff\s+/) {
            $mcnt = 0;  # restart _MSC_VER count for this file
            $dcnt++;
            if ($line =~ /\\\.svn\\/) {
               $i++;
               for (; $i < $cnt; $i++) {
                  $line = $lines[$i];
                  chomp $line;
                  if ($line =~ /^diff\s+/) {
                     $dcnt++;
                     if ( !($line =~ /\\\.svn\\/) ) {
                        last;
                     }
                  }
               }
               last if ($i == $cnt);   # if we ran out of lines, in a .svn diff
            }
            $fcnt++;
            @arr = split(/\s/,$line);
            $ac = scalar @arr;
            for ($j = 1; $j < $ac; $j++) {
               $itm = $arr[$j];
               if ( !($itm =~ /^-/) ) {
      				# ($nm, $dir, $ext) = fileparse( $itm, qr/\.[^.]*/ );
      				#($nm, $dir) = fileparse($itm);
                  $nm = sub_base_svn_dir($itm);
                  ($bnm,$dir) = fileparse($nm);
                  $dir = ".\\" if (length($dir) == 0);
                  #                 0    1  2  3     4
                  push(@file_list, [$nm, 0, 0, $dir, $bnm]);
                  $msg = '';
                  if (defined $file_hash{$nm}) {
                     prtw( "WARNING: $dcnt: $nm NOTE: Is a REPEAT file name!" );
                  } else {
                     $file_hash{$nm} = 0;
                  }
                  prt("$dcnt $nm ($dir)\n");
                  last;
               }
            }
            #prt( "$dcnt: $line\n" );
         } else {
            if ($line =~ /#\s*if(n*)def\s+_MSC_VER/) {
               $mcnt++;
               $file_list[-1][1] = $mcnt;
               $file_hash{$nm} = $mcnt;
            }
         }
         push(@nlines,$line);
      }
   } else {
      prt("ERROR: Unable to open $fil...\n" );
   }
   prt("Done total $dcnt diffs, collecting $fcnt in file_list. (".scalar @file_list.")\n");
   return @nlines;
}

sub add_file_list() {
   my ($file,$mcnt,$max,$i,$wrap,$msg,$cnt,$wmcnt,$tmp);
   my ($done, $dir, $cdir, $had_out, $last_dir, $ndmcnt);
   $max = scalar @file_list;
   $wrap = 4;
   $wmcnt = 0;
   $cnt = 0;
   for ($i = 0; $i < $max; $i++) {
      $mcnt = $file_list[$i][1];
      $wmcnt++ if ($mcnt);
   }
   $msg = "\nListing $max files, first $wmcnt showing _MSC_VER switch for each...\n";
   prt($msg);
   $cnt = 0;
   for ($i = 0; $i < $max; $i++) {
      $file_list[$i][2] = 0;
   }
   $cdir = '';
   $had_out = 1;
   $last_dir = '';
   while ($had_out) {
      $cnt = 0;
      $had_out = 0;
      $tmp = '';
      $ndmcnt = 0;
      if (length($cdir) == 0) {
         # get the first, and next directory
         for ($i = 0; $i < $max; $i++) {
            $done = $file_list[$i][2];
            $mcnt = $file_list[$i][1];
            if ($mcnt && ($done == 0)) {
               $ndmcnt++;
               $cdir  = $file_list[$i][3];
               if (length($last_dir)) {
                  if ($cdir ne $last_dir) {
                     $tmp = "Doing directory [$cdir]\n";
                     last;
                  }
               } else {
                  $tmp = "Doing directory [$cdir]\n";
                  last;
               }
            }
         }
      }
      if (length($cdir) == 0) {
         prt( "Done first list since no new directories...\n" );
         prtw("WARNING: Found at least 1 NOT done, with _MSC_VER count\n") if ($ndmcnt);
         next;
      }
      $msg .= $tmp;
      prt($tmp);
      for ($i = 0; $i < $max; $i++) {
         $file = $file_list[$i][0];
         $mcnt = $file_list[$i][1];
         $done = $file_list[$i][2];
         $dir  = $file_list[$i][3];
         if ($done == 0) {
            $had_out++;
            if ($mcnt && ($dir eq $cdir)) {
               $file_list[$i][2] = 1;
               $msg .= "$file($mcnt) ";
               $cnt++;
               if ($cnt == $wrap) {
                  $cnt = 0;
                  $msg .= "\n";
               }
            }
         }
      }
      $msg .= "\n" if ($cnt);
      $last_dir = $cdir;
      $cdir = '';
   }
   $cnt = $max - $wmcnt;
   if ($cnt) {
      $tmp = "and listing $cnt files, with no _MSC_VER switch...\n";
      $msg .= $tmp;
      prt($tmp);
      $cnt = 0;
      for ($i = 0; $i < $max; $i++) {
         $file = $file_list[$i][0];
         $mcnt = $file_list[$i][1];
         $done = $file_list[$i][2];
         $dir  = $file_list[$i][3];
         if ($mcnt == 0) {
            $msg .= "$file ";
            $cnt++;
            if ($cnt == $wrap) {
               $cnt = 0;
               $msg .= "\n";
            }
         }
      }
      $msg .= "\n" if ($cnt);
   }
   return $msg;
}

sub give_help() {
   prt( "$0 [-h] in_file [out_file] [svn_dir]\n" );
   prt( " -h (--help) - this brief help, and exit 1\n" );
   prt( " in_file     - input file to process\n" );
   prt( " out_file    - output file. default=$out_file\n" );
   prt( " svn_dir     - first directory of the compare. default=$svn_dir\n" );
   prt( "Alternative commands...\n");
   prt( " -in FILE    - set input file.\n" );
   prt( " -out FILE   - set output file.\n" );
   prt( " -dir DIR    - set first directory.\n" );
   prt( "Command error will exit with greater than 1\n" );
   exit(1);
}

sub process_args($) {
   my ($rav) = shift;
   my ($arg, $max, $i, $cnt, $len, $tmp, $equ);
   $cnt = 0;
   my $got_if = 1;
   my $got_of = 2;
   my $got_sd = 4;
   $max = scalar @{$rav};
   for ($i = 0; $i < $max; $i++) {
      $arg = ${$rav}[$i];
      if ($arg =~ /^-/) {
         # deal with switch
         if ($arg =~ /^-(-*)h/) {
            give_help();
         } elsif ($arg =~ /^-(-*)in(=*)(.*)$/) {
            $equ = $2;
            $tmp = $3;
            if (length($equ)) {
               $in_file = $tmp;
               prt( "Set input file to [$in_file]\n" );
               $cnt |= $got_if;
            } else {
               if (($i + 1) < $max) {
                  $i++;
                  $arg = ${$rav}[$i];
                  $in_file = $arg;
                  prt( "Set input file to [$in_file]\n" );
                  $cnt |= $got_of;
               } else {
                  prt("ERROR: [$arg] requires following infile name. aborting...\n");
                  exit(5);
               }
            }
         } elsif ($arg =~ /^-(-*)out(=*)(.*)$/) {
            $equ = $2;
            $tmp = $3;
            if (length($equ)) {
               $out_file = $tmp;
               prt( "Set output file to [$out_file]\n" );
               $cnt |= $got_of;
            } else {
               if (($i + 1) < $max) {
                  $i++;
                  $arg = ${$rav}[$i];
                  $out_file = $arg;
                  prt( "Set output file to [$out_file]\n" );
                  $cnt |= $got_of;
               } else {
                  prt("ERROR: [$arg] requires following outfile name! aborting...\n");
                  exit(5);
               }
            }
         } elsif ($arg =~ /^-(-*)dir(=*)(.*)$/) {
            $equ = $2;
            $tmp = $3;
            if (length($equ)) {
               $svn_dir = $tmp;
               prt( "Set directory to [$svn_dir]\n" );
               $cnt |= $got_sd;
            } else {
               if (($i + 1) < $max) {
                  $i++;
                  $arg = ${$rav}[$i];
                  $svn_dir = $arg;
                  prt( "Set directory to [$svn_dir]\n" );
                  $cnt |= $got_of;
               } else {
                  prt("ERROR: [$arg] requires following directory name! aborting...\n");
                  exit(5);
               }
            }
         } else {
            prt("ERROR: unknown argument [$arg]\n");
            exit(4);
         } 
      } else {
         # not a switch - then order is important
         if ( !($cnt & $got_if) ) {
            $in_file = $arg;
            prt( "Set input file to [$in_file]\n" );
            $cnt |= $got_if;
         } elsif ( !($cnt & $got_of) ) {
            $out_file = $arg;
            prt( "Set output file to [$out_file]\n" );
            $cnt |= $got_of;
         } elsif ( !($cnt & $got_sd) ) {
            $svn_dir = $arg;
            $svn_dir .= "\\" if !($svn_dir =~ /\\$/);
            prt( "Set SVN directory to [$svn_dir]\n" );
            $cnt |= $got_sd;
         } else {
            prt("ERROR: unknown argument [$arg]\n");
            exit(3);
         }
      }
   }
}

process_args(\@ARGV);
prt( "$0 ... processing $in_file to $out_file...\n" );
my @nls = process_file($in_file);
my $txt = join("\n",@nls);
$txt .= "\n";
$txt .= add_file_list();
write2file($txt,$out_file);
prt("Written $out_file... \n");
show_warnings();

# system($out_file);
close_log($outfile,1);
exit(0);

# eof
