#!/usr/bin/perl

exit if !defined $ARGV[0];

@lines = get_makefile($ARGV[0]);
@lines = get_useful(@lines);
while (@includes = grep(/^include /, @lines)) {
	@lines = grep(!/^include /, @lines);
	get_vars(@lines);
	foreach (@includes) {
		chomp;
		s/^include //;
		$file = expand($_);
		@lines = (@lines, get_useful(get_makefile($file)));
	}
}
get_vars(@lines);
@targets = get_targets(@lines);
@targets = sort(@targets);

foreach (@targets) {
	print "$_\n";
}

sub
get_makefile {
	my $file = shift(@_);
	open FILE, $file;
	my @lines = <FILE>;
	close FILE;
	return @lines;
}

sub
get_useful {
	my $line = "";
	my @retarr;
	foreach (@_) {
		s/\#.*//;
		$line .= $_ if (!/^[\#[:space:]]/);
		if (!/\\$/) {
			$line =~ s/\\\n//g;
			@retarr = (@retarr, $line);
			$line = "";
		}
	}
	$line =~ s/\\\n//g;
	@retarr = (@retarr, $line);
	return @retarr;
}

sub
get_vars {
	foreach (@_) {
		next if (!/=/);
		/([^[:space:]]*)[[:space:]]*:?=[[:space:]]*(.*)/;
		$vars{$1} = $2;
	}
}

sub
get_targets {
	my @targets;
	foreach (@_) {
		next if (/=/);
		next if (!/:/);
		/([^:]*):(.*)/;
		@targets = (@targets, split(' ', expand($1)));
	}
	return @targets;
}

sub
expand {
	my $line = shift @_;
	return $line if (!($line =~ /\$/));
	my @bits = split('\$', $line);
	my $skip = 0;
	my $ret = shift @bits;
	foreach (@bits) {
		if ($skip) {
			$ret .= "\$$_";
			$skip = 0;
			next;
		}
		if ($_ eq "") {
			$ret .= "\$";
			$skip = 1;
			next;
		}
		if (/^\(/) {
			/^\((.*)\)(.*)/;
			$exp = $1;
			$rest = $2;
		} else {
			/^\{(.*)\}(.*)/;
			$exp = $1;
			$rest = $2;
		}
		if (!defined $exp) {
			$ret .= "\$$_";
			next;
		}
		if (defined $vars{$exp}) {
			if ($vars{$exp} =~ /\$\(shell/) {
				$cmd = $vars{$exp};
				$cmd =~ s/^\$\(shell //;
				$cmd =~ s/\)$//;
				$val = `$cmd`;
				chomp($val);
				$ret .= "$val$rest";
			} else {
				$ret .= "$vars{$exp}$rest";
			}
		} else {
			$ret .= "\$$_";
		}
	}
	return $line if ($ret eq $line);
	return expand($ret);
}
