#! /usr/bin/perl -wT
#
# $FreeBSD: CVSROOT/logcheck,v 1.16 2001/05/14 15:08:57 jlemon Exp $
# 
# This hack is to sanitise the results of what the user may have
# "done" while editing the commit log message.. :-)   Peter Wemm.
#
# Note: this uses an enhancement to cvs's verifymsg functionality.
# Normally, the check is advisory only, the FreeBSD version reads
# back the file after the verifymsg file so that this script can
# make changes.
#

use strict;

<<<<<<< logcheck
#====================================================
# Get our configuration.
my $CVSROOT = $ENV{'CVSROOT'} || "/home/ncvs";
require         "$CVSROOT/CVSROOT/config.pm";
use vars        qw(@RCSTEMPLATE_KEYWORDS);
import config;
#====================================================
=======
>>>>>>> 1.16

<<<<<<< logcheck
=======
############################################################
#
# Configurable options
#
############################################################

# These are the optional headers that can be filled at the end of
# each commit message.  The associated value is a regular-expression
# that is used to type-check the entered value.  If the match failed
# then the commit is rejected.  (See rcstemplate).
my %HEADERS = (
	"Reviewed by"		=> '.*',
	"Submitted by"		=> '.*',
	"Obtained from"		=> '.*',
	"Approved by"		=> '.*',
	"PR"			=> '.*',
	"MFC after"		=> '\d+(?:\s+(?:days?|weeks?|months?))?'
);



#############################################################
#
# Main Body
#
############################################################
>>>>>>> 1.16

<<<<<<< logcheck
my $filename = shift;
my $tmpfile = $filename . "tmp";
die "Usage: logcheck filename\n" unless $filename;


open IN, "< $filename" or
	die "logcheck: Cannot open for reading: $filename: $!\n";

open OUT, "> $tmpfile" or
	die "logcheck: Cannot open for writing: $tmpfile: $!\n";

# In-place edit the result of the user's edit on the file.
my $blank = 0;	# true if the last line was blank
my $first = 0;	# true if we have seen the first real text
while(<IN>) {
	# Dont let CVS: lines upset things, strip them out.
	next if /^CVS:/;

	chomp;		# strip trailing newline
	s/\s+$//;	# strip trailing whitespace

	# collapse multiple blank lines, and trailing blank lines.
	if (/^$/) {
		# Blank line. Remember in case more text follows.
		$blank = 1;
=======
my $filename = shift;
die "Usage: logcheck filename\n" unless $filename;




# Read the log file in, stripping 'CVS:' lines and removing trailing
# white spaces.
open IN, "< $filename" or
    die "logcheck: Cannot open for reading: $filename: $!\n";
my @log_in = map { s/^(.*?)\s*$/$1/; $1 } grep { !/^CVS:/ } <IN>;
close IN;

# Remove leading, trailing and duplicate blank lines.
my $i = 0;
while ($i < scalar(@log_in)) {
	unless ($log_in[$i] or $log_in[$i + 1]) {
		splice(@log_in, $i, 1);
>>>>>>> 1.16
		next;
<<<<<<< logcheck
	} else {
		# Delete rcstemplate keywords if they
		# only have whitespace after them.
		my $keyword;
		foreach my $k (@RCSTEMPLATE_KEYWORDS) {
			$keyword = 1 if /^$k$/i;
=======
        }
        ++$i;
}
shift @log_in unless $log_in[0];

# Filter out blank templated entries, and type check if necessary.
# (looking from the end of the commit message backwards)
my $j = scalar(@log_in) - 1;
my $error = 0;
while ($j >= 0  and  my $header = $log_in[$j]) {
	--$j;

	if ($header =~ /^(.*?):\s*(.*)$/) {
		my $header = $1;
		my $value = $2;
		my $pattern = $HEADERS{$header};

		# Ignore unrecognised headers.
		unless (defined($pattern)) {
		### 	print "Warning: unknown template header: $header\n";
			next;
>>>>>>> 1.16
		}
		next if $keyword;

		# Filter out the template header if it's blank.
		unless ($value) {
			splice(@log_in, $j + 1, 1);
			next;
		}

		# Type check the header
		unless ($value =~ /^$pattern$/) {
			print "Error: syntax check failed for: $header\n";
			++$error;
			next;
		}

	} else {
		### XXX
		# We're here because we saw a line that didn't match
		# a template header (no ':').  This could be a continuation
		# line from the previous header, or the log message proper.
		# We don't know, so run the risk of checking the last paragraph
		# of the log message for headers.
		next;
	}
}
<<<<<<< logcheck
close IN;
close OUT;
=======


# Write the modified log file back out.
my $tmpfile = $filename . "tmp";
open OUT, "> $tmpfile" or
    die "logcheck: Cannot open for writing: $tmpfile: $!\n";
print OUT map { "$_\n" } @log_in;
close OUT;


# Stop the commit if there was a problem with the template headers.
if ($error) {
	print "There were $error errors in the template headers.\n";
	print "Please fix the log message and commit again.\n";
	print "A copy of your log message was saved in $tmpfile.\n";
	exit 1;
}



# Nuke likely editor backups.
unlink "$filename.~";
unlink "$filename.bak";
>>>>>>> 1.16

<<<<<<< logcheck
unlink $filename . "~";		# Nuke likely editor backups..
unlink $filename . ".bak";	# Nuke likely editor backups..
=======
>>>>>>> 1.16

<<<<<<< logcheck
rename $tmpfile, $filename or
	die "logcheck: Could not rename $tmpfile to $filename: $!";
=======
# Overwrite the log message with our sanitised one.  (See the comment
# block at the top of this script for an explaination of why.)
rename($tmpfile, $filename) or
    die "logcheck: Could not rename $tmpfile to $filename: $!";
>>>>>>> 1.16

exit 0;
