#!/usr/bin/perl -w

my %defd = ();
my %used = ();
my %comd = ();
my %trace = ();
my $show_common = 0;

my %def_ok = map { $_ => 1 } qw(
	main
	alloc_report
	have_git_dir
	prepare_git_cmd
	print_string_list
	tm_to_time_t
	unsorted_string_list_has_string
	xdl_atol
	xdl_cha_first
	xdl_cha_next
	xdl_mmfile_size
	xdl_num_out
	xdl_recs_cmp
);

while (@ARGV) {
	$_ = shift(@ARGV);

	if (/^-t$/) {
		my $trace_symbol = shift @ARGV;
		die("$0: missing argument to -t option") if !$trace_symbol;
		$trace{$trace_symbol}++;
		next;
	}

	if ($_ eq '-c') {
		$show_common = 1;
		next;
	}
}

for (<*.o>, <*/*.o>, <*/*/*.o>) {
	my $obj = $_;
	open(I, "-|", qw(nm -gC), $obj) or die;
	while (<I>) {
		unless (/^[0-9a-f ]+([A-Z]) (\S*)$/) {
			print STDERR "? $_";
			next;
		}
		next if ($2 =~ /^\.refptr\./);
		if (exists $trace{$2}) {
			print "-- $2: type $1, object $obj\n";
		}
		if ($1 eq "C") {
			if($show_common) {
				print "++ $2: type $1, object $obj\n";
			}
			if (exists $comd{$2}) {
				$used{$2}++;
			}
			else {
				$comd{$2}++;
				push @{$defd{$obj}}, $2;
			}
		} elsif ($1 eq "U") {
			$used{$2}++;
		} else {
			push @{$defd{$obj}}, $2;
		}
	}
	close I;
}

for my $obj (sort keys %defd) {
	my $syms = $defd{$obj};
	for my $sym (@$syms) {
		next if exists $used{$sym} or exists $def_ok{$sym};
		print "$obj	- $sym\n";
	}
}

