user_data, db: improve how returned user data is handled
[smatch.git] / smatch_scripts / call_tree.pl
blob745a5376b56b4e19bfbc8866713785d1cbac06a2
1 #!/usr/bin/perl
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.
7 use strict;
9 sub usage()
11 print("call_tree.pl <smatch output file>\n");
12 print("call_tree.pl finds paths between two functions\n");
13 exit(1);
16 my %param_map;
18 my $UNKNOWN = 1;
19 my $NOTFOUND = 2;
20 my $FOUND = 3;
22 my $path;
24 sub print_path()
26 my $i = 0;
28 foreach my $func (@{$path}) {
29 if ($i++) {
30 print(", ");
32 print("$func");
34 print("\n");
35 print("\n");
38 sub recurse($$)
40 my $link = shift;
41 my $target = shift;
42 my $found = 0;
44 if ($link =~ /$target/) {
45 print_path();
46 return 1;
48 if (%{$param_map{$link}}->{found} == $NOTFOUND) {
49 return 0;
52 %{$param_map{$link}}->{found} = $NOTFOUND;
54 foreach my $l (@{%{$param_map{$link}}->{links}}){
55 push(@{$path}, $l);
56 $found = recurse($l, $target);
57 if (!$found) {
58 pop(@{$path});
59 } else {
60 last;
64 return $found;
67 sub search($$)
69 my $start_func = shift;
70 my $end_func = shift;
72 foreach my $link (@{%{$param_map{$start_func}}->{links}}){
73 %{$param_map{$start_func}}->{found} = $NOTFOUND;
74 foreach my $l (@{%{$param_map{$start_func}}->{links}}){
75 %{$param_map{$l}}->{found} = $NOTFOUND;
77 $path = [$start_func, $link];
78 %{$param_map{$link}}->{found} = $UNKNOWN;
79 recurse($link, $end_func);
83 sub add_link($$)
85 my $one = shift;
86 my $two = shift;
88 if (!defined($param_map{$one})) {
89 $param_map{$one} = {found => $UNKNOWN, links => []};
91 push @{$param_map{$one}->{links}}, $two;
94 sub load_all($)
96 my $file = shift;
98 open(FILE, "<$file");
99 while (<FILE>) {
100 if (/.*?:\d+ (.*?)\(\) info: func_call (.*)/) {
101 add_link("$1", "$2");
106 sub set_all_unknown()
108 my $i = 0;
110 foreach my $func (keys %param_map){
111 %{$param_map{$func}}->{found} = $UNKNOWN;
115 my $file = shift();
116 if (!$file) {
117 usage();
120 if (! -e $file) {
121 printf("Error: $file does not exist.\n");
122 exit(1);
125 print("Loading functions...\n");
126 load_all($file);
128 while (1) {
129 my $start_func;
130 my $end_func;
132 print("Enter the start function: ");
133 $start_func = <STDIN>;
134 $start_func =~ s/^\s+|\s+$//g;
135 print("Enter the target function: ");
136 $end_func = <STDIN>;
137 $end_func =~ s/^\s+|\s+$//g;
140 print("$start_func to $end_func\n");
141 if ($start_func =~ /./ && $end_func =~ /./) {
142 search($start_func, $end_func);
145 set_all_unknown();