#!/perl -w
# NAME: showbuildsrcs.pl
# AIM: Analyse the build.log for sources compiled
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_file = 'S:\geoff\projects\Handbrake\hb-svn\build\log\build3a.txt';
my $base_dir = '/home/geoff/projects/Handbrake/hb-svn/';

sub trim_act_dir($) {
	my ($dir) = shift;
	my $ch = substr($dir,0,1);
	my $l = length($base_dir);
	$dir = substr($dir,1) if ($ch eq '`');
	$dir =~ s/'$//;

	if (substr($dir,0,$l) eq $base_dir) {
		$dir = substr($dir,$l);
	}
	return $dir;
}

sub has_c_param($) {
	my ($ln) = shift;
	my @arr = split(/\s/,$ln);
	my $ac = scalar @arr;
	for (my $i = 0; $i < $ac; $i++) {
		my $p = $arr[$i];
		if ($p eq '-c') {
			if (($i + 1) < $ac) {
				return 1;
			}
		}
	}
	return 0;
}

sub get_c_param($) {
	my ($lnc) = shift;
	my @arr = split(/\s/,$lnc);
	my $ac = scalar @arr;
	for (my $i = 0; $i < $ac; $i++) {
		my $p = $arr[$i];
		if ($p eq '-c') {
			if (($i + 1) < $ac) {
				my $res = $arr[$i+1];
				if ($res eq '-o') {
					my $i2 = $i + 1 + 2;
					if ($i2 < $ac) {
						if ( ($arr[$i2] eq '`test') && (($i2 + 2) < $ac) ) {
							$res = $arr[$i2+2];
							$res =~ s/'//g;
							return $res;
						} else {
							return $arr[$i2];
						}
					}
					return "$res??? CHECKME!!!";
				}
				return $res;
			}
		}
	}
	return "";
}

sub has_o_param($) {
	my ($ln) = shift;
	my @arr = split(/\s/,$ln);
	my $ac = scalar @arr;
	for (my $i = 0; $i < $ac; $i++) {
		my $p = $arr[$i];
		if ($p eq '-o') {
			if (($i + 1) < $ac) {
				return 1;
			}
		}
	}
	return 0;
}

sub get_o_param($) {
	my ($lno) = shift;
	my @arr = split(/\s/,$lno);
	my $ac = scalar @arr;
	for (my $i = 0; $i < $ac; $i++) {
		my $p = $arr[$i];
		if ($p eq '-o') {
			if (($i + 1) < $ac) {
				return $arr[$i+1];
			}
		}
	}
	return "";
}

sub process_in_file($) {
	my ($inf) = shift;
	my @srcstack = ();
	if (open INF, "<$inf") {
		my @lines = <INF>;
		close INF;
		my ($lncnt, $line, $actdir, $ch, $indir, $actfil, $pline, $tmp);
		my ($has_c, $has_o);
		$lncnt = scalar @lines;
		prt( "Got $lncnt lines from $inf...\n" );
		$indir++;
		my @dirstack = ();
		my $lnnum = 0;
		$pline = '';
		foreach $line (@lines) {
			chomp $line;
			$lnnum++;
			# make[2]: Entering directory `/home/geoff/projects/Handbrake/hb-svn/build/contrib/a52dec/a52dec'
			if ($line =~ /make.*: Entering directory (.+)/) {
				$actdir = trim_act_dir($1);
				##prt( "Entering [$actdir]\n" );
				$indir++;
				push(@dirstack,$actdir);
			} elsif ($indir) {
				# make[2]: Leaving directory `/home/geoff/projects/Handbrake/hb-svn/build/contrib/a52dec/a52dec'
				if ($line =~ /make.*: Leaving directory (.+)/) {
					$actdir = trim_act_dir($1);
					if (@dirstack) {
						if ($dirstack[-1] eq $actdir) {
							pop @dirstack;
							$indir--;
						} else {
							prt( "Leaving  [$actdir] NOT STACK TOP!!!\n" );
						}
					} else {
						prt( "Leaving  [$actdir] NO STACK!!!\n" );
					}
				}
			}
			if ($indir) {
				#/usr/bin/gcc -DHAVE_CONFIG_H -I. -I. -I../include -I../include -I../include -O3 -fomit-frame-pointer -c bitstream.c -o bitstream.o
				if ($line =~ /^\/usr\/bin\/gcc/) {
					$has_c = has_c_param($line);
					$has_o = has_o_param($line);
					$actfil = get_c_param($line);
					if (length($actfil)) {
						prt( "$lnnum:SRC: $actdir/$actfil\n" );
						push(@srcstack, [$actfil, $actdir, 0, 0, ""]);
					} else {
						$actfil = get_o_param($line);
						if (length($actfil)) {
							prt( "$lnnum: OUT: $actdir/$actfil\n" );
							prt("\n");
							push(@srcstack, [$actfil, $actdir, 1, 0, $line]);
						} else {
							prt( "NO -c nor -o! $lnnum:[$line]\n" );
						}
					}
				} elsif ($line =~ /^ranlib\s+(.+)/) {
					$tmp = "".($lnnum - 1);
					if ($pline =~ /^chmod/) {
						# skip this
					} else {
						prt( "$tmp: Lib: [$pline]\n\n" );
						push(@srcstack, [$pline, $actdir, 2, 0, $line]);
					}
				}

			}
			$pline = $line;	# keep this line
		}

		if (@dirstack) {
			prt( "WARNING: still stacked items...\n" );
		} else {
			prt( "Directory stack correctly NULL\n" );
		}
		prt( "Done $lnnum lines... ($lncnt)\n" );
	} else {
		prt( "ERROR: can not open [$inf]\n" );
	}
	return @srcstack;
}

sub output_entry($$$$) {
	my ($src,$dir,$flag,$rdc) = @_;
	if ($flag == 0) {
		prt( "\n" ) if ($$rdc == 0);
		prt( "SRC: $dir/$src\n" );
		$$rdc++;
	} elsif ($flag == 1) {
		prt( "Out: $dir/$src\n" );
		prt("\n") if ($$rdc);
		$$rdc = 0;
	} else {
		prt( "Lib: $src\n" );
		prt("\n") if ($$rdc);
		$$rdc = 0;
	}
}


sub process_srcs($) {
	my ($rsrcs) = shift;
	my $scnt = scalar @$rsrcs;
	my ($dir, $src, $flag, $done, $cont, $adir, $dcnt);
	prt( "Extracted $scnt sources, and results...\n" );
	$cont = 1;
	$adir = '';
	my %donedirs = ();
	$dcnt = 0;
	while ($cont) {
		$cont = 0;
		for (my $i = 0; $i < $scnt; $i++) {
			$src = $$rsrcs[$i][0];
			$dir = $$rsrcs[$i][1];
			$flag = $$rsrcs[$i][2];
			$done = $$rsrcs[$i][3];
			if (!$done) {
				if (!defined $donedirs{$dir}) {
					$dcnt = 0;
					$adir = $dir;
					$donedirs{$dir} = 1;
					$cont++;
					output_entry($src,$dir,$flag,\$dcnt);
					$$rsrcs[$i][3] = 1;
					$i++;
					for (; $i < $scnt; $i++) {
						$src = $$rsrcs[$i][0];
						$dir = $$rsrcs[$i][1];
						$flag = $$rsrcs[$i][2];
						$done = $$rsrcs[$i][3];
						if (!$done && ($dir eq $adir)) {
							output_entry($src,$dir,$flag,\$dcnt);
							$$rsrcs[$i][3] = 1;
						}
					}
				}
			}
		}
	}
	prt( "Done $scnt sources, and results...\n\n" );
}

my @srcs = process_in_file($in_file);

process_srcs(\@srcs);

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


# eof
