#!/perl -w
# NAME: cmpconfigs.pl
# AIM: Compare 2 config files...
# 8/21/2009 - geoff mclane - http://geoffair.net/mperl/
use strict;
use warnings;
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);
prt( "$0 ... Hello, World ...\n" );

my $in_file1 = 'S:\geoff\projects\Handbrake\hb-svn\build1\contrib\ffmpeg\ffmpeg-r19067\config.h';
my $in_file2 = 'C:\Projects\hb\ffmpeg\build\msvc\conf.h';

# comments dropped
# // until end of line
# /* until */
sub drop_comments($) {
	my ($l) = shift;
	my $ll = length($l);
	my $ic = 0;
	my ($j, $c, $pc, $nc);
	$pc = '';
	my $newl = '';
	for ($j = 0; $j < $ll; $j++) {
		$c = substr($l,$j,1);
		$nc = (($j + 1) < $ll) ? substr($l,$j+1,1) : ' ';
		if ($ic) {
			if (($c eq '/')&&($pc eq '*')) {
				$ic = 0;
			}
		} elsif (($c eq '/') && ( ($nc eq '*') || ($nc eq '/') ) ) {
			$ic = 1;
			return $newl if ($nc eq '/');
		}
		$pc = $c;
		$newl .= $c if (!$ic);
	}
	return $newl;
}

sub is_config_other($) {
	my ($typ) = shift;
	if ( ($typ =~ /^CONFIG_/) && 
		!(($typ =~ /_PARSER/)||($typ =~ /_DECODER/)||($typ =~ /_ENCODER/)||($typ =~ /_MUXER/)||($typ =~ /_DEMUXER/)) ) {
		return 1;
	}
	return 0;
}


sub	out_hash_list($) { # like ( \%same );
	my ($rh) = shift;
	my ($v1, $k1, $v2, $tcnt);
	# ENCODERS
	$v2 = 0;
	$tcnt = 0;
	foreach $k1 (keys %$rh) {
		$v1 = $$rh{$k1};
		if ($k1 =~ /^CONFIG_(.+)_ENCODER/) {
			$tcnt++;
		}
	}
	prt( "// $tcnt CONFIG ENCODERS\n") if ($tcnt);
	$tcnt = 0;
	foreach $k1 (sort keys %$rh) {
		$v1 = $$rh{$k1};
		if ($k1 =~ /^CONFIG_(.+)_ENCODER/) {
			prt( "#define $k1 $v1\n" );
		} else {
			$v2++;
		}
	}

	# DECODERS
	$tcnt = 0;
	foreach $k1 (keys %$rh) {
		$v1 = $$rh{$k1};
		if ($k1 =~ /^CONFIG_(.+)_DECODER/) {
			$tcnt++
		}
	}
	prt( "// $tcnt CONFIG DECODERS\n") if ($tcnt);
	foreach $k1 (sort keys %$rh) {
		$v1 = $$rh{$k1};
		if ($k1 =~ /^CONFIG_(.+)_DECODER/) {
			prt( "#define $k1 $v1\n" );
		} else {
			$v2++;
		}
	}

	# PARSERS
	$tcnt = 0;
	foreach $k1 (keys %$rh) {
		$v1 = $$rh{$k1};
		if ($k1 =~ /^CONFIG_(.+)_PARSER/) {
			$tcnt++;
		}
	}
	prt( "// $tcnt CONFIG PARSER\n") if ($tcnt);
	foreach $k1 (sort keys %$rh) {
		$v1 = $$rh{$k1};
		if ($k1 =~ /^CONFIG_(.+)_PARSER/) {
			prt( "#define $k1 $v1\n" );
		} else {
			$v2++;
		}
	}

	# MUXER
	$tcnt = 0;
	foreach $k1 (keys %$rh) {
		$v1 = $$rh{$k1};
		if ($k1 =~ /^CONFIG_(.+)_MUXER/) {
			$tcnt++
		}
	}
	prt( "// $tcnt CONFIG MUXER\n") if ($tcnt);
	foreach $k1 (sort keys %$rh) {
		$v1 = $$rh{$k1};
		if ($k1 =~ /^CONFIG_(.+)_MUXER/) {
			prt( "#define $k1 $v1\n" );
		} else {
			$v2++;
		}
	}
	# DEMUXER
	$tcnt = 0;
	foreach $k1 (keys %$rh) {
		$v1 = $$rh{$k1};
		if ($k1 =~ /^CONFIG_(.+)_DEMUXER/) {
			$tcnt++
		}
	}
	prt( "// $tcnt CONFIG DEMUXER\n") if ($tcnt);
	foreach $k1 (sort keys %$rh) {
		$v1 = $$rh{$k1};
		if ($k1 =~ /^CONFIG_(.+)_DEMUXER/) {
			prt( "#define $k1 $v1\n" );
		} else {
			$v2++;
		}
	}

	$tcnt = 0;
	foreach $k1 (keys %$rh) {
		$v1 = $$rh{$k1};
		if ( is_config_other($k1) ) {
			$tcnt++;
		}
	}
	prt( "// $tcnt CONFIG OTHERS\n") if ($tcnt);
	foreach $k1 (keys %$rh) {
		$v1 = $$rh{$k1};
		if ( is_config_other($k1) ) {
			prt( "#define $k1 $v1\n" );
		}
	}

	prt("\n") if ($v2);
	$tcnt = 0;
	foreach $k1 (sort keys %$rh) {
		$v1 = $$rh{$k1};
		if ( !($k1 =~ /^CONFIG_/) ) {
			$tcnt++;
		}
	}

	prt( "// $tcnt OTHER OTHERS\n") if ($tcnt);
	foreach $k1 (sort keys %$rh) {
		$v1 = $$rh{$k1};
		if ( !($k1 =~ /^CONFIG_/) ) {
			prt( "#define $k1 $v1\n" );
		}
	}
}


sub load_cfg_file($) {
	my ($fil) = shift;
	my %hash = ();
	if (open INF, "<$fil") {
		my @lns = <INF>;
		close INF;
		my $lnc = scalar @lns;
		prt( "Got $lnc lines, from $fil...\n" );
		my $lnnum = 0;
		foreach my $ln (@lns) {
			$lnnum++;
			chomp $ln;
			$ln = trim_all($ln);
			$ln = drop_comments($ln);
			if ($ln =~ /#\s*define\s+(.+)/) {
				my $def = $1;
				my @a = split(/\s/,$def);
				if (scalar @a > 1) {
					my $dfn = $a[0];
					my $dfv = $a[1];
					if (defined $hash{$dfn}) {
						prt( "$dfn: already defined as ".$hash{$dfn}.", now changed to $dfv!\n" );
					}
					$hash{$dfn} = $dfv;
				} else {
					prt("WARNING: $lnnum: did not split [$ln]\n");
				}
			}
		}
	} else {
		prt("ERROR: unable to open [$fil]...\n");
		exit 1;
	}
	return %hash;
}

sub compare_2_hashes($$) {
	my ($rh1, $rh2) = @_;
	my $h1c = scalar keys(%$rh1);
	my $h2c = scalar keys(%$rh2);
	prt( "Compare $h1c with $h2c...\n" );
	my ($k1, $v1, $k2, $v2, $tcnt);
	my %diffs = ();
	my %newd = ();
	my %same = ();
	my $nd1 = 0;
	my $df1 = 0;
	my $sm1 = 0;
	my $nd2 = 0;
	# run file 1 hash, and compare to 2
	foreach $k1 (keys %$rh1) {
		$v1 = $$rh1{$k1};
		if (defined $$rh2{$k1}) {
			$v2 = $$rh2{$k1};
			if ($v1 != $v2) {
				prt("DIFF: $k1 $v1 vs $v2\n");
				$df1++;
				$diffs{$k1} = $v1;
			} else {
				$sm1++;
				$same{$k1} = $v1;
			}
		} else {
			prt("H1: $k1 $v1, NOT defined in 2\n" );
			$newd{$k1} = $v1;
			$nd1++;
		}
	}

	# run file 2 hash, and compare to 1, only for missing
	foreach $k2 (keys %$rh2) {
		$v2 = $$rh2{$k2};
		if (defined $$rh1{$k2}) {
			# already dealt with these...
		} else {
			prt("H2: $k2 $v2, NOT defined in 1\n" );
			$nd2++;
		}
	}


	prt( "// Summary: Same $sm1, Diff $df1, NDef1 $nd1, NDef2 $nd2\n" );
	prt( "// ".YYYYMMDD(time())." generated by $pgmname for Handbrake project.\n" );
	
	if ($sm1) {
		prt( "// Same SAME $sm1...\n" );
		out_hash_list( \%same );
		prt( "// Done Same SAME $sm1...\n" );
	}
	if ($df1) {
		prt( "\nSuggested differences $df1...\n" );
		out_hash_list( \%diffs );
		prt( "Done $df1 differences...\n" );
	}
	if ($nd1) {
		prt( "\nSuggested additions to 2 - $nd1...\n" );
		out_hash_list( \%newd );
		prt( "Done $nd1 additions...\n" );
	}
	prt( "// Done: Same $sm1, Diff $df1, NDef1 $nd1, NDef2 $nd2\n" );
}

################################################
# My particular time 'translation'
sub YYYYMMDD() {
	#  0    1    2     3     4    5     6     7     8
	my ($tm) = shift;
    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($tm);
	$year += 1900;
	$mon += 1;
	my $ymd = "$year/";
	if ($mon < 10) {
		$ymd .= '0'.$mon.'/';
	} else {
		$ymd .= "$mon/";
	}
	if ($mday < 10) {
		$ymd .= '0'.$mday;
	} else {
		$ymd .= "$mday";
	}
	return $ymd;
}


my %hash1 = load_cfg_file($in_file1);
my %hash2 = load_cfg_file($in_file2);

compare_2_hashes( \%hash1, \%hash2 );

close_log($outfile,1);
exit(0);

# eof
