#!/usr/bin/perl
# This scripts goes through the kernel sources and
# prints assignments of (void*) functions that
# get type-changed:
#   type *x = (type*) function().
# The first argument is the kernel source directory, additional 
# arguments override the embedded function name list.


$kernel_dir=shift || die "Need a directory argument (kernel sources),\n" .
"and optionally function names.\n" .
"If none are given, a default list is taken.\n";

# Get source files
@ARGV=split(/\0/, `find "$kernel_dir" -type f -iname "*.c" -print0`);
die "No sources found.\n" unless @ARGV;

# Read whole files, and look for such assignments.
$/=undef;
while (<>)
{
	$changes=0;
#		- struct netdev_private *np = (struct netdev_private *)dev->priv;
#		+ struct netdev_private *np = dev->priv;
#	or just
#	   lp = (struct i596_private *) dev->priv;
	$changes++ while 
		s{ 
			( (?: struct \s+ \w+ \s* \* \s*)? \w+ \s+ = ) \s* 
				\( [\w\s\*]+ \* \s* \) \s* 
				( \w+ \s* -> \s* priv(?:ate)? \s* ; )
		}{$1 $2}xgo;

	if ($changes)
	{
		open(DIFF, qq(| diff -up --label "$ARGV" "$ARGV" --label "$ARGV" -)) 
		|| die "Cannot start diff program: $!\n";
		print DIFF $_;
		close DIFF;
	}
}
