#! /usr/bin/perl

#This parses a file generated with "cvs log -rrelease_0_81:" to give the
#log messages of all files that have changed.  An executive summary is
#provided at the end.

$MsgIndex = 0;

sub SaveCurrentUnique
{
local($CurrentMsg, $File, $Date) = @_;
local($i);

	$TotalMessages += 1;
	$i = 0;
	while ($i < $#AllMessages)
	{
		if ($AllMessages[$i] eq $CurrentMsg)
		{
		    $AllMessagesFiles[$i] = join(" ", $AllMessagesFiles[$i], $File);
		    last;
		}
		$i += 1;
	}
#	if ($i == 0 || $i == $#AllMessages)
	if ($#AllMessages < 0 || $i == $#AllMessages)
	{
	    $AllMessages[$MsgIndex] = $CurrentMsg;
#	    if ($AllMessagesFiles[$MsgIndex] eq "")
#	    {
		$AllMessagesFiles[$MsgIndex] = $File;
#	    }
#	    else
#	    {
#		$AllMessagesFiles[$MsgIndex] = join(" ", $AllMessagesFiles[$MsgIndex], $File);
#	    }
	    $AllMessagesId[$MsgIndex] = (split(';', $Date, 3))[1];
	    ($AllMessagesId[$MsgIndex] = $AllMessagesId[$MsgIndex]) =~ s/^[ \t\n]*//;
	    ($Date = $Date) =~ s/^date: //;
	    ($Date = $Date) =~ s/;.*$//;
	    $AllMessagesDates[$MsgIndex] = $Date;
	    $MsgIndex += 1;
	}
}

sub DoRevisions
{
local($File, $LastRev) = @_;
local($Rev);
local($CurrentMsg);
local($Date);

	$CurrentMsg = "";
	while (!(($Rev = <STDIN>) =~ m/^=============================================================================$/))
	{
	    chop($Rev);
	    if ($Rev =~ m/^revision /)
	    {
		$Rev =~ s/^revision //;
		if ($Rev != $LastRev)
		{
#		    printf("%s %s\n",$File, $Rev);
		    while ($Text = <STDIN>)
		    {
			if ((($Text) =~ m/^=============================================================================$/))
			{
#			    printf("\n\n");
			    &SaveCurrentUnique($CurrentMsg, "$File" . "($Rev)", $Date);
			    $CurrentMsg = "";
			    return;
			}
			elsif ((($Text) =~ m/^----------------------------$/))
			{
			    &SaveCurrentUnique($CurrentMsg, "$File" . "($Rev)", $Date);
			    $CurrentMsg = "";
			    last;
			}
			else
			{
#			    printf("   $Text");
			    if (! ($Text =~ m/^date:/))
			    {
				$CurrentMsg .= "$Text";
			    }
			    else
			    {
			    	$Date = $Text;
			    }
			}
		    }
		}
		else
		{
#		    printf("\n\n");
		    return;
		}
	    }
	}
	#printf("End Revisions %s\n\n", $File);
#	printf("\n\n");
}

sub DoFile
{
local($File) = @_;
local($WorkFile, $Head, $Branch, $Locks, $Access, $Symbolic, $Line);

	$WorkFile = <STDIN>;
	chop($WorkFile);
	$WorkFile =~ s/^Working file: //;
	$Head = <STDIN>;
	chop($Head);
	$Head =~ s/^head: //;
	$Branch = <STDIN>;
	$Locks = <STDIN>;
	$Access = <STDIN>;
	$Line = <STDIN>;
	$Symbolic = <STDIN>;
	if (! ($Symbolic =~ m/^\t/))
	{
	    $Symbolic = $Head;
	}
	else
	{
	    while (($Line = <STDIN>) =~ m/^\t/)
	    {
		if ($Line =~ m/^[\t]+${Target}:/)
		{
		    $Symbolic = $Line;
		    last;
		}
	    }
	    chop($Symbolic);
	}
	if (! ($Symbolic =~ m/^\t/))
	{
	    $Symbolic = $Head;
	}
	else
	{
	    $Symbolic =~ s/^.*: //;
	}
	if ($Symbolic != $Head)
	{
#	    printf("%s Current rev %s Last Release %s\n",$WorkFile, $Head, $Symbolic);
	    $Changed++;
	    push(@Summary, "$WorkFile $Head $Symbolic");
	    while (!(($_ = <STDIN>) =~ m/^----------------------------$/))
	    {
	    }
	    &DoRevisions($WorkFile, $Symbolic);
	}
	else
	{
#	    printf("%s - No change\n", $WorkFile);
	    $NotChanged++;
	    push(@Summary, "$WorkFile $Head $Symbolic No Change");
	    while (!(<STDIN> =~ m/^=============================================================================$/))
	    {
	    }
	}
}

$Target = @ARGV[0];
while (<STDIN>)
{
	chop;
        if (! (m/^RCS file:.*\/Attic\/.*/)) {
	    if (m/^RCS file: /)
	    {
		&DoFile($_);
	    }
	} 
}

$i = 0;
while ($i < $#AllMessages)
{
	$Messages{$AllMessagesDates[$i]} = "$AllMessagesId[$i]\n" . join("\n", split(/ /, $AllMessagesFiles[$i])) . "\n\n$AllMessages[$i]";
#	print "$AllMessagesDates[$i]\n";
#	print "$AllMessagesFiles[$i]\n\n";
#	print "$AllMessages[$i]";
#	print "===================\n\n";
	$i += 1;
}
foreach (sort(keys(%Messages)))
{
	print "==============\n$_";
	print "$Messages{$_}";
}
print "==============\n$_";

printf("\n\nExecutive Summary\n");
printf("Of %d files, %d changed, and %d had no change\n\n",$Changed + $NotChanged, $Changed, $NotChanged);
$FileLen = 0;
foreach (@Summary)
{
	($File,$Cur,$Last,$Stat) = split(' ', $_, 4);
	if (length($File) > $FileLen)
	{
		$FileLen = length($File);
	}
}
$Format = sprintf("%%-%ds %%-12s %%-12s %%s\n", $FileLen);
printf($Format, "File","Current Rev.","Last Release", "");
foreach (@Summary)
{
	($File,$Cur,$Last,$Stat) = split(' ', $_, 4);
	printf($Format, $File, $Cur, $Last, $Stat);
}
