#! /usr/bin/perl
# Randy Dunlap <rddunlap@osdl.org>
# 2005-05-02
#
#Matt Mackall wrote:
#I think a mail robot that you could send patches to that would detect:
#- quoted printable
#- line wrapping
#- tab damage
#- wrong directory level
#- non-unidiff
#- added trailing whitespace
#- etc.
#- lines longer than 80 characters
#- use of // style comments
#
#..would be quite useful. Then we could just say "your patch is
#damaged, resend to patch-tester@foo.org until it says it looks ok".
#
#Any volunteers? 
#-- 

$tabcount = 0;
$spaces_run = 0;
$trailing_ws = 0;
$double_slashes = 0;
$bad_encodings = 0;
$not_unidiff = 0;
$not_pdiff = 0;
$bad_subdir = 0;

%kernel_dirs = ("arch", 1, "crypto", 1, "drivers", 1, "fs", 1,
		"include", 1, "init", 1, "ipc", 1, "kernel", 1,
		"lib", 1, "mm", 1, "net", 1, "scripts", 1,
		"security", 1, "sound", 1, "usr", 1, "Documentation", 1);

# get input file name:
$INPUTNAME = $ARGV[0];

if (length ($INPUTNAME) == 0) {
        print "usage: check-patch.pl patchfile\n\n";
        exit 1;
}

if (! open (INPUTNUM, "<$INPUTNAME")) {
        print "cannot open '$INPUTNAME'\n\n";
        exit 2;
}

print "$INPUTNAME :\n";

readpatch: while ($line = <INPUTNUM>)
{
	chomp $line;
	# print "deb: #line = {$line}\n";

	$tabcount++ if $line =~ /\t/;
	$spaces_run++ if $line =~ /    /;
	$trailing_ws++ if $line =~ /^\+.*[ \t]$/;
	$double_slashes++ if $line =~ /\/\//;

	if ($line =~ /Content-Transfer-Encoding:/i) {
		if (($line =~ /base64/i) ||
		    ($line =~ /binary/i) ||
		    ($line =~ /quoted-printable/i)) {
			$bad_encodings++;
			print "bad encoding: $line\n";
		}
	}

	if ($line =~ /^diff/) {
		if ($line !~ /-.*u/) {
			print "appears not to be a -u diff\n";
			$not_unidiff++;
		}
		if ($line !~ /-.*p/) {
			print "appears not to be a -p diff\n";
			$not_pdiff++;
		}
	}

	if ($line =~ /^--- / || $line =~ /^\+\+\+ /) {
		$filename = substr($line, 4);
		@diffline = split(' ', $filename); # filename date time
		@fnparts = split('/', $diffline[0]);
		$subdir = $fnparts[1];
		if ((substr($subdir, length($subdir) - 1, 1) eq '/') &&
		       ($kernel_dirs{$subdir} != 1)) {
			$ending = substr($subdir, length($subdir) - 1, 1);
			print "bad sub-dir level {$ending}[$subdir]: $line\n";
			$bad_subdir++;
		}
	}
} # end readpatch

close (INPUTNUM);

print "  tab count: $tabcount\n";
print "  spaces_run count: $spaces_run\n";

print "  trailing whitespace: $trailing_ws\n";
print "  bad encodings: $bad_encodings\n";
print "  '//' comments: $double_slashes\n";
print "  not -u diff: $not_unidiff\n";
print "  not -p diff: $not_pdiff\n";
print "  bad sub-dir level: $bad_subdir\n";

if ($tabcount == 0 && $spaces_run > 0) {
	print "  WARNING: no tabs found, lots of spaces found; not a good sign\n";
}

$errs = $trailing_ws + $bad_encodings + $double_slashes + $not_unidiff + $not_pdiff
	+ $bad_subdir;

if ($errs == 0) {
	print "  PASS (no errors)\n";
}
else {
	print "  ##### $errs error(s) #####\n";
}

# end.
