#!/usr/bin/gawk
BEGIN\
{
	errors = 0
	total_size = 0
	comment_size = 0
	file = ""
	opening_comment_groups = 0;
	closing_comment_groups = 0;
}
match($0, "BAUSTELLE") > 0\
{
	print FILENAME":"FNR" : BAUSTELLE!"
	errors++
}
match($0, "[^A-Za-z0-9_][a-z]*[0-9a-z_]*__[A-Za-z][A-Z0-9_a-z]*[^_a-z0-9A-Z]") > 0 && !/__[A-Z]+__/\
{
	if (line_done == 0)
	{
		print FILENAME":"FNR" : old-style variable/argument name: " substr($0, RSTART + 1, RLENGTH - 2)
		errors++
	}
	line_done = 1
}
match($0, "\\( *void *\\)") > 0\
{
	if (line_done == 0)
	{
		print FILENAME":"FNR" : use foo() instead of foo(void) for method declarations: " $0
		errors++
	}
	line_done = 1
}
match($0, "[^A-Za-z0-9_][a-z]*[0-9a-z_]*__[A-Za-z][A-Z0-9_a-z]*$") > 0 && !/__[A-Z]+__/\
{
	if (line_done == 0)
	{
		print FILENAME":"FNR" : old-style variable/argument name: " substr($0, RSTART + 1, RLENGTH - 1)
		errors++
	}
	line_done = 1
}
match($0, "[^A-Za-z0-9\\\\_]_[A-Z0-9_a-z]+[^_a-z0-9A-Z]") > 0 && !/__[A-Z]+__/\
{
	if (line_done == 0)
	{
		print FILENAME":"FNR" : old-style private member name: " substr($0, RSTART + 1, RLENGTH - 2)
		errors++
	}
	line_done = 1
}
match($0, "[^A-Za-z0-9\\\\_]_[A-Z0-9_a-z]+$") > 0 && !/__[A-Z]+__/\
{
	if (line_done == 0)
	{
		print FILENAME":"FNR" : old-style private member name: " substr($0, RSTART + 1, RLENGTH - 1)
		errors++
	}
	line_done = 1
}
match($0, "[^A-Za-z0-9\\\\_]_[A-Z0-9_]+[^_a-z0-9A-Z]") > 0 && !/__[A-Z]+__/ \
{
	if (line_done == 0)
	{
		print FILENAME":"FNR" : old-style macro name: " substr($0, RSTART + 1, RLENGTH - 2)
		errors++
	}
	line_done = 1
}
match($0, "[^A-Za-z0-9\\\\_]_[A-Z0-9_]+$") > 0 && !/__[A-Z]+__/\
{
	if (line_done == 0)
	{
		print FILENAME":"FNR" : old-style macro name: " substr($0, RSTART + 1, RLENGTH - 1)
		errors++
	}
	line_done = 1
}
match($0, "[^A-Za-z0-9\\\\_]_[A-Z][0-9A-Za-z_]*[^_a-z0-9A-Z]") > 0 \
{
	if (line_done == 0)
	{
		print FILENAME":"FNR" : old-style class/type name: " substr($0, RSTART + 1, RLENGTH - 2)
		errors++
	}
	line_done = 1
}
match($0, "[^A-Za-z0-9\\\\_]_[A-Z][0-9A-Za-z_]*$") > 0 \
{
	if (line_done == 0)
	{
		print FILENAME":"FNR" : old-style class/type name: " substr($0, RSTART + 1, RLENGTH - 1)
		errors++
	}
	line_done = 1
}
match($0, "[^A-Z]TIterator[a-zA-Z]*") > 0 || \
match($0, "[^A-Z]TConst[a-zA-Z]*") > 0 || \
match($0, "[^A-Z]TForward[a-zA-Z]*") > 0 || \
match($0, "[^A-Z]TReverse[a-zA-Z]*") > 0 || \
match($0, "[^A-Z]TRandom[a-zA-Z]*") > 0 \
{
	if (line_done == 0)
		print FILENAME":"FNR" : old-style iterator name: " substr($0, RSTART + 1, RLENGTH - 1)
	line_done = 1
}
{	
	# Start of new file:
	if (FNR == 1)
	{
		start = match($0,"// \\$Id")
		if (start != 1)
		{
			print FILENAME":"FNR" : missing RCS Id in line 1. Please add \"// $Id: check_coding,v 1.5.32.1 2007/03/25 22:02:47 oliver Exp $\" in the first line."
			errors++
		}

		if (total_size > 0)
		{
			if (comment_size / total_size < 0.05)
			{
				printf  "%s: not enough comments: %.1f%%\n", file,  100.0 * (comment_size / total_size)
				errors++
			}
		}
		
		# check whether each DOC++ group has an opening and a closing brace
		if (opening_comment_groups != closing_comment_groups)
		{
			print file ": " opening_comment_groups " opened DOC++ groups, but " closing_comment_groups " closed!"
			errors++
		} 
		file = FILENAME
		total_size = 0
		comment_size = 0
		opening_comment_groups = 0;
		closing_comment_groups = 0;
	}

	line_length = length($0)

	# check for DOC++ groups: check for correct grouping
	if ($0 ~ /\/\/@/)
	{
		if ($0 ~ /\/\/@{/)
		{
			opening_comment_groups++;
		} 
		else if ($0 ~ /\/\/@}/)
		{
			closing_comment_groups++;
			if (closing_comment_groups > opening_comment_groups)
			{
				print file ":" FNR ": closing DOC++ comment group without opening group!"
				errors++
			}
		}
		else 
		{
			print file ":" FNR ": strange DOC++ group!"
			errors++
		}
	}

	if ((t = index($0, "//")) != 0) 
	{
		$0 = substr($0, 1, t-1)
	}
	if ((t = index($0, "/*")) != 0) {
			 # value will be "" if t is 1
			 tmp = substr($0, 1, t - 1)
			 u = index(substr($0, t + 2), "*/")
			 while (u == 0) {
						if (getline <= 0) {
								 m = "unexpected EOF or error"
								 m = (m ": " ERRNO)
								 print m > "/dev/stderr"
								 exit
						}
						t = -1
						u = index($0, "*/")
			 }
			 # substr expression will be "" if */
			 # occurred at end of line
			 $0 = tmp substr($0, t + u + 3)
	}
	total_size += line_length
	comment_size += line_length - length($0)
	line_done = 0;
}
END\
{
	# check whether each DOC++ group has an opening and a closing brace
	if (opening_comment_groups != closing_comment_groups)
	{
		print file ": " opening_comment_groups " opened DOC++ groups, but " closing_comment_groups " closed!"
		errors++
	}

	if (total_size > 0)
	{
		if (comment_size / total_size < 0.05)
		{
			printf  "%s: not enough comments: %.1f%%\n", file,  100.0 * (comment_size / total_size)
			errors++
		}
	}

	print ""

	if (errors == 0)
	{
		print "No errors found!"
	} else {
		print errors" error(s) found!"
	}



}
