#!/usr/bin/perl
use FileHandle;

my %instdir = ();

# Take a Makefile line of the form:
# obj-XXXXX = some_directory/ some_module.o
#
# All directories are processed by including the referenced Makefile and
# removing the directory.  The modules are added to the list of modules
# to install.  Prints the edited line to OUT.
# Arguments: directory Makefile is in, the objects, original line(s) from
# Makefile (with newlines intact).
sub check_line($$$)
{
	my $dir = shift;
	my $objs = shift;
	my $orig = shift;
	my $count = 0;

	foreach(split /\s+/, $objs) {
		if (m|/$|) { # Ends in /, means it's a directory
			# Delete this directory from original Makefile line
			$orig =~ s/$_[ \t]*//;
			$_ .= 'Makefile';
			# print STDERR "open new makefile $dir/$_\n";
			open_makefile("$dir/$_");
			next;
		}

		# It's a file, add it to list of files to install
		s/\.o$/.ko/;
		my $idir = $dir;
		$idir =~ s|^../linux/drivers/media/||;
		$instdir{$idir}{$_} = 1;
		$count++;
	}
	# Removing any tailling whitespace, just to be neat
	$orig =~ s/[ \t]+$//mg;

	# Print out original line, less directories, if there is anything
	# still there
	print OUT $orig if($count);
}

# Uses the string being assigned from a line of the form:
# EXTRA_CFLAGS += -Idrivers/media/something -Dwhatever
#
# All the -Idrivers/media/something options get deleted.  All the source
# files are linked into the v4l directory and built from there, so and -I
# option for them is unnecessary.  The line is printed to OUT if there is
# anything left after that.
sub remove_includes($$)
{
	my $flags = shift;
	my $orig = shift;
	my $count = 0;

	foreach(split /\s+/, $flags) {
		if (m|^-Idrivers/media|) {
			# Remove any -I flags from original Makefile line
			$orig =~ s/$_[ \t]*//;
			next;
		}
		$count++;	# Something wasn't deleted
	}
	$orig =~ s/[ \t]+$//mg;

	# Print out original line if there is anything we didn't delete
	print OUT $orig if($count);
}

sub open_makefile($) {
	my $file = shift;
	my $in = new FileHandle;
	my $orig;

	# only open a given Makefile once
	return if exists $makefiles{$file};
	$makefiles{$file} = 1;

	$file =~ m|^(.*)/[^/]*$|;
	my $dir = $1;

	# print STDERR "opening $file (dir=$dir)\n";
	$file =~ m|.*/(linux/.*)$|;
	print OUT "# Including $1\n";
	open $in, $file;

	while (<$in>) {
		# print STDERR "Line: $_";
		# Skip comment lines
		if (/^\s*#/) {
			print OUT $_;
			next;
		}
		m/^\s*-?include/ and die "Can't handle includes! In $file";

		# Handle line continuations
		if (/\\\n$/) {
			$_ .= <$in>;
			redo;
		}

		# $orig is what we will print, $_ is what we will parse
		$orig = $_;
		# Eat line continuations in string we will parse
		s/\s*\\\n\s*/ /g;
		# Eat comments
		s/#.*$//;

		if (/^\s*obj-.*:?=\s*(\S.*?)\s*$/) {
			# print STDERR "obj matched '$1'\n";
			check_line($dir, $1, $orig);	# will print line for us
			next;
		}
		if (/^\s*EXTRA_CFLAGS\s+\+?=\s*(\S.*?)\s*$/) {
			# print STDERR "cflags matched '$1'\n";
			remove_includes($1, $orig);	# will print line for us
			next;
		}
		print OUT $orig;
	}
	close $in;
}

open OUT, '>Makefile.media' or die 'Unable to write Makefile.media';
open_makefile('../linux/drivers/media/Makefile');

# Creating Install rule
print OUT "media-install::\n";
print OUT "\t\@echo \"Stripping debug info from files:\"\n";
print OUT "\t\@strip --strip-debug \$(inst-m)\n\n";

while (my ($dir, $files) = each %instdir) {
	print OUT "\t\@echo -e \"\\nInstalling \$(KDIR26)/$dir files:\"\n";
	print OUT "\t\@install -d \$(KDIR26)/$dir\n";
	print OUT "\t\@for i in ", join(' ', keys %$files), ";do ";
	print OUT "if [ -e \"\$\$i\" ]; then echo -n \"\$\$i \";";
	print OUT " install -m 644 -c \$\$i \$(KDIR26)/$dir; fi; done; echo;\n\n";
}
print OUT "\t/sbin/depmod -a \${KERNELRELEASE}\n\n";

# Creating Remove rule
print OUT "media-rminstall::\n";
print OUT "\t\@echo -e \"\\nRemoving old \$(DEST) files\\n\"\n";

while ( my ($dir, $files) = each(%instdir) ) {
	print OUT "\t\@echo -e \"\\nRemoving old \$(KDIR26)/$dir files:\"\n";
	print OUT "\t\@files='", join(' ', keys %$files), "'; ";

	print OUT "for i in \$\$files;do if [ -e \$(KDIR26)/$dir/\$\$i ]; then ";
	print OUT "echo -n \"\$\$i \";";
	print OUT " rm \$(KDIR26)/$dir/\$\$i; fi; done; ";

	print OUT "for i in \$\$files;do if [ -e \$(KDIR26)/$dir/\$\$i.gz ]; then ";
	print OUT "echo -n \"\$\$i.gz \";";
	print OUT " rm \$(KDIR26)/$dir/\$\$i.gz; fi; done; echo;\n\n";
}

# Print dependencies of Makefile.media
print OUT "Makefile.media: ../linux/drivers/media/Makefile \\\n";
print OUT join(" \\\n", map("\t../linux/drivers/media/$_/Makefile", keys %instdir));
print OUT "\n";
close OUT;
