#!/usr/bin/perl

# checks for:
# - [patch] in subject
# - encoding (no base64, quoted-printable)
# - presence of Signed-off-by
# - looks -p1 appliable?
# - "hi/hello/description" strings
# - line wrapping
# - trailing whitespace
# - no tabs


$header = 2;
$body = 0;
$warnings = 0;
$tabcount = 0;
$signedoffby = 0;

# update this when needed
$kroot = "(CREDITS|MAINTAINERS|Makefile|README|REPORTING-BUGS|".
	"Documentation\/|arch\/|crypto\/|drivers\/|fs\/|include\/|init\/|".
	"ipc\/|kernel\/|lib\/|mm\/|net\/|scripts\/|security\/|sound\/|usr\/)";

while (<>) {
	# skip the first line, there's probably a better way
	if ($header == 2) {
		$header = 1;
		next;
	}

	# header checks
	if ($header == 1) {
		$header = 0 if (!/^[a-z\-]+:|^[\t ]+/i);
		$boundary = $1 if (/boundary="([^"]+)"/);
		print("To:$1\n") if (/^From:(.*)$/i);
		print("Subject: [Checked] $1\n") if (/^Subject: (.*)$/i);

		if (/^Subject: (?!.*?\[.*?patch.*?\])/i) {
			print("\nNo [PATCH] in Subject line\n\n");
			$warnings++;
		}
		next;
	}

	$in_boundary = 1 if ($boundary && /^--\Q$boundary\E/);
	$in_boundary = 0 if (/^$/); # hmm... do boundaries always end like this?

	# don't print boundaries
	print("> $_") if ($in_boundary != 1);

	if (/^Content-Transfer-Encoding: (quoted-printable|base64)/) {
		print("> $_\nTeach your mailer not to encode messages.\n\n");
		goto err_out;
	}

	# no checks inside boundaries
	next if ($in_boundary == 1);

	# between header and patch, description
	if ($body != 1) {
		$signedoffby = 1 if (/^Signed-off-by:.*<.*\@.*>$/);

		# --- is end of body marker, but there might be diffstat so +++
		if (/^\+\+\+ /) {
			$body = 1;
			if ($signedoffby == 0) {
				print("\nThere should be a Signed-off-by:\n\n");
				$warnings++;
			}
		}
		if (/^(\+\+\+|---) (?![^\/]+\/$kroot|\/dev\/null)/) {
			print("\nPatch should be -p1 appliable.\n\n");
			$warnings++;
		}
		if (/^ *[hH](i|ello)( +\w+)? *[,\.\!]? *$/) {
			print("\nHi/hello in patch description.\n\n");
			$warnings++;
		}
		if (/^ *[dD]escription *:\s*/) {
			print("\n\"Description\" in patch description.\n\n");
			$warnings++;
		}
		if (/^-- $/) {
			print("\nPlease, no .sig in patch description.\n\n");
			$warnings++;
		}
	} else {
	# patch
		if (!/^([+\- @]|$|diff)/) {
			print("\nLooks like a wrapped line.\n\n");
			$warnings++;
		}
		if (/^\+.*[\t ]$/) {
			print("\nYou add trailing whitespace.\n\n");
			$warnings++;
		}
		if (/\t/) {
			$tabcount++;
		}
	}
}

if ($tabcount == 0) {
	print("\nNo tabs detected... this might be ok, but is usualy error\n" .
			"  caused by copy&paste from terminal\n\n");
	$warnings++;
}

if ($warnings != 0) {
	print("\n$warnings warnings to work on... good luck\n\n");
} else {
	print("\nPatch seems OK\n\n");
}

err_out:
#print("If you think output is invalid, mail <domen\@coderock.org>\n");
