1#!/usr/bin/perl
2
3# This script is supposed to help use the param_mapper output.
4# Give it a function and parameter and it lists the functions
5# and parameters which are basically equivalent.
6
7use strict;
8
9sub usage()
10{
11    print ("trace_params.pl <smatch output file> <function> <parameter>\n");
12    exit(1);
13}
14
15my %param_map;
16
17my $UNKNOWN  = 1;
18my $NOTFOUND = 2;
19my $FOUND    = 3;
20
21sub recurse($$)
22{
23    my $link = shift;
24    my $target = shift;
25    my $found = 0;
26
27    if ($link =~ /$target/) {
28        $param_map{$link}->{found} = $FOUND;
29        return 1;
30    }
31
32    if ($param_map{$link}->{found} == $FOUND) {
33        return 1;
34    }
35    if ($param_map{$link}->{found} == $NOTFOUND) {
36        return 0;
37    }
38
39    $param_map{$link}->{found} = $NOTFOUND;
40    foreach my $l (@{$param_map{$link}->{links}}){
41        $found = recurse($l, $target);
42        if ($found) {
43            $param_map{$link}->{found} = $FOUND;
44            return 1;
45        }
46    }
47
48    return 0;
49}
50
51sub compress_all($$)
52{
53    my $f = shift;
54    my $p = shift;
55    my $target = "$f%$p";
56
57    foreach my $link (keys %param_map){
58        recurse($link, $target);
59    }
60}
61
62sub add_link($$)
63{
64    my $one = shift;
65    my $two = shift;
66
67    if (!defined($param_map{$one})) {
68        $param_map{$one} = {found => $UNKNOWN, links => []};
69    }
70    push @{$param_map{$one}->{links}}, $two;
71}
72
73sub load_all($)
74{
75    my $file = shift;
76
77    open(FILE, "<$file");
78    while (<FILE>) {
79        if (/.*?:\d+ (.*?)\(\) info: param_mapper (\d+) => (.*?) (\d+)/) {
80            add_link("$1%$2", "$3%$4");
81        }
82    }
83}
84
85sub print_found()
86{
87    foreach my $func (keys %param_map){
88        my $tmp = $param_map{$func};
89
90        if ($tmp->{found} == $FOUND) {
91            my ($f, $p) = split(/%/, $func);
92            print("$f $p\n");
93        }
94    }
95}
96
97my $file = shift();
98my $func = shift();
99my $param = shift();
100
101if (!$file or !$func or !defined($param)) {
102    usage();
103}
104
105if (! -e $file) {
106    printf("Error:  $file does not exist.\n");
107    exit(1);
108}
109
110load_all($file);
111compress_all($func, $param);
112print_found();
113