#!perl -w
# NAME: cleandiff.pl
# AIM: To remove some things from an input diff file ...
# 1 - remove Only in blah blah ...
# 2 - remove diff of .dsp files ...
# and write results to an output file
# 2009/11/11 - remove diff of vcproj/sln/bak/old/user files
# and because added -N to diff, see diffall.bat, then remove lines 'Binary files ...'
# BUT even then TOO MANY THINGS were pulled in by the 'N', so removed it!
# 11/28/2008 - compare results with chglist.txt, if found
# 11/2/2008 geoff mclane http://geoffair.net/fg
use strict;
use warnings;
use Time::gmtime;

my $in_file = 'tempdiff.txt';
my $out_file = 'temp2diff.txt';
my $out_chg = 'tempchged.txt';
my $chk_file = 'chglist.txt';

sub get_YYYYMMDD_UTC($) {
    my ($t) = shift;
    # sec, min, hour, mday, mon, year, wday, yday, and isdst.
    my $tm = gmtime($t);
    my $m = sprintf( "%04d/%02d/%02d",
        $tm->year() + 1900, $tm->mon() + 1, $tm->mday());
    return $m;
}

sub excluded_lines($) {
	my ($txt) = shift;
	if ($txt =~ /^diff\s+.+\.dsp$/i) {
		return 1;
	}
	if ($txt =~ /^diff\s+.+(\\|\/)CVS(\\|\/).+$/) {
		return 1;
	}
    # 2009/11/11 - also exclude VCPROJ (and SLN) files
    return 1 if ($txt =~ /^diff\s+.+\.vcproj\s*$/i);
    return 1 if ($txt =~ /^diff\s+.+\.sln\s*$/i);
    return 1 if ($txt =~ /^diff\s+.+\.bak\s*$/i);
    return 1 if ($txt =~ /^diff\s+.+\.old\s*$/i);
    return 1 if ($txt =~ /^diff\s+.+\.user\s*$/i);
    return 1 if ($txt =~ /^diff\s+.+\.manifest\s*$/i);
    return 1 if ($txt =~ /^diff\s+.+\.dep\s*$/i);
	return 0;
}

parse_args(@ARGV);

process_file($in_file, $out_file);

exit(0);

sub give_help {
	prt( "Brief HELP for $0 script ...\n" );
	prt( "$0 -in:input_file -out:output_file\n" );
	ort( "Defaults: in:$in_file, out:$out_file\n" );
	exit(0);
}

sub parse_args {
	my (@av) = @_;
	my ($arg, $ch, $val);
	while(@av) {
		$arg = shift @av;
		$ch = substr($arg,0,1);
		if ($arg =~ /\?/) {
			give_help();
		} elsif (($ch eq '-')||($ch eq '/')) {
			$val = substr($arg,1);
			if ($val =~ /^in:/) {
				$in_file = substr($val,3);
				prt( "Set input file to $in_file ...\n" );
			} elsif ($val =~ /^out:/) {
				$out_file = substr($val,4);
				prt( "Set output file to $out_file ...\n" );
			} else {
				prt( "ERROR: Unknown argument [$arg]!\n" );
				give_help();
			}
		} else {
			prt( "ERROR: Unknown argument [$arg]!\n" );
			give_help();
		}
	}
}

sub prt {
	my ($txt) = shift;
	print $txt;
}

# 11/28/2008 - compare with chglist.txt ($chk_file), if available
sub do_change_compare {
	my (@nlines) = @_;
	my ($line, $line2, $fnd, @nf1, @nf2, $lncnt, $newlns, @lines);
	if (-f $chk_file) {
		if (open INF, "<$chk_file") {
			@lines = <INF>;
			close INF;
			$lncnt = scalar @lines;
			$newlns = scalar @nlines;
			prt( "Comparing $newlns results in $out_chg, with $lncnt lines from $chk_file ...\n" );
			@nf1 = ();
			@nf2 = ();
			foreach $line (@lines) {
				chomp $line;
				$fnd = 0;
				foreach $line2 (@nlines) {
					if ($line eq $line2) {
						$fnd = 1;
						last;
					}
				}
				if (!$fnd) {
					push(@nf1,$line);
				}
			}
			foreach $line (@nlines) {
				chomp $line;
				$fnd = 0;
				foreach $line2 (@lines) {
					if ($line eq $line2) {
						$fnd = 1;
						last;
					}
				}
				if (!$fnd) {
					push(@nf2,$line);
				}
			}
			if (@nf2) {
				prt( "Found ".scalar @nf2." new line(s) in $out_chg, NOT in $chk_file ...\n" );
				foreach $line (@nf2) {
					prt("$line\n");
				}
			} else {
				prt( "ALL new lines in $out_chg, found in $chk_file ...\n" );
			}
			if (@nf1) {
				prt( "Found ".scalar @nf1." line(s) in $chk_file, NOT in new $out_chg ...\n" );
				foreach $line (@nf1) {
					prt("$line\n");
				}
			} else {
				prt( "ALL $chk_file lines found in new lines $out_chg ...\n" );
			}
			my $diff = (scalar @nf1) + (scalar @nf2);
			prt("Done comp of new $out_chg($newlns), with $chk_file($lncnt), with $diff diferences to be checked!\n");
		} else {
			prt("WARNING: Unable to open $chk_file ... for comparing results ...\n");
		}
	}
	# ignore if $chk_file NOT found
}

sub process_file {
	my ($fil, $out) = @_;
	my (@lines, $line, $lncnt, $i, $txt, $lnnum, $gotbgn, $dlines, $folder);
	my @nlines = ();
	my @chged = ();
	my $newlns = 0;
	$gotbgn = 0;
	$dlines = 0;
	$folder = '';
	if (open INF, "<$fil") {
		@lines = <INF>;
		close INF;
		$lncnt = scalar @lines;
		prt( "Process $lncnt lines from $fil ...\n" );
		$lnnum = 0;
		for ($i = 0; $i < $lncnt; $i++) {
			$line = $lines[$i];
			chomp $line;
			$lnnum++;
            next if ($line =~ /^Only\s+in\s+/);         # 'Only in ...'
            next if ($line =~ /^Binary\s+files\s+/);    # 'Binary files ...'
			if ($line =~ /^#BEGIN (.+)\s*$/) {
				$folder = $1;
				$gotbgn = 1;
			} elsif ($line =~ /^#DIFF /) {
				$gotbgn = 2;
			} elsif ($line =~ /^#END /) {
				$gotbgn = 0;
			} elsif ( excluded_lines($line) ) {
				$i++;	# bump to next, and skip for a while
				for (; $i < $lncnt; $i++) {
					$line = $lines[$i];
					chomp $line;
        			$lnnum++;
                    next if ($line =~ /^Only\s+in\s+/);         # 'Only in ...'
                    next if ($line =~ /^Binary\s+files\s+/);    # 'Binary files ...'
					if ($line =~ /^diff\s+.+/) {
						if ( !( excluded_lines($line) ) ) {
							last;
						}
					} elsif ($line =~ /^#END /) {
						$gotbgn = 0;
						$dlines = 0;
						last;
					}
				}
			}
			if ($line =~ /^\+\+\+\s+([\w\.\\\/]+)/) {
				push(@chged,$1);
			}
			push(@nlines,$line);
			$newlns++;
		}
        # OUTPUT the 'new' lines
        $txt = "# Massaged with 'cleandiff.pl' on ".get_YYYYMMDD_UTC(time())."\n";
        $txt .= "# IN file '$fil'($lncnt). OUT file '$out'($newlns) - New lines follow - \n";
		$txt .= join("\n",@nlines);
		$txt .= "\n";
		if (open OUT, ">$out") {
			print OUT $txt;
			close OUT;
			prt("Written $newlns to $out ... discarded ".($lncnt - $newlns)." lines ...\n" );
			if (@chged) {
				$txt = join("\n",@chged);
				$txt .= "\n";
				if (open OUT, ">$out_chg") {
					print OUT $txt;
					close OUT;
					prt("Written changed files to $out_chg...\n" );
					do_change_compare(@chged);
				} else {
					prt( "WARNING: Unable to create $out_chg ...\n" );
				}
			} else {
				prt( "WARNING: Did NOT get any change files ...\n" );
			}
		} else {
			prt( "ERROR: Unable to CREATE/WRITE file $out ... check name, location...\n" );

		}
	} else {
		prt( "ERROR: Unable to OPEN/READ file $fil ... check name, location...\n" );
	}
}

# eof - cleandiff.pl
