1*1f5207b7SJohn Levon#!/usr/bin/perl -w
2*1f5207b7SJohn Levon
3*1f5207b7SJohn Levonuse strict;
4*1f5207b7SJohn Levonuse DBI;
5*1f5207b7SJohn Levonuse Scalar::Util qw(looks_like_number);
6*1f5207b7SJohn Levon
7*1f5207b7SJohn Levonsub usage()
8*1f5207b7SJohn Levon{
9*1f5207b7SJohn Levon    print "usage:  $0 <project> <smatch_warns.txt> <db_file>\n";
10*1f5207b7SJohn Levon    exit(1);
11*1f5207b7SJohn Levon}
12*1f5207b7SJohn Levon
13*1f5207b7SJohn Levonmy %too_common_funcs;
14*1f5207b7SJohn Levonsub get_too_common_functions($$$)
15*1f5207b7SJohn Levon{
16*1f5207b7SJohn Levon    my $path = shift;
17*1f5207b7SJohn Levon    my $project = shift;
18*1f5207b7SJohn Levon    my $warns = shift;
19*1f5207b7SJohn Levon
20*1f5207b7SJohn Levon    open(FUNCS, "grep 'SQL_caller_info: ' $warns | grep '%call_marker%' | cut -d \"'\" -f 6 | sort | uniq -c | ");
21*1f5207b7SJohn Levon
22*1f5207b7SJohn Levon    while (<FUNCS>) {
23*1f5207b7SJohn Levon        if ($_ =~ /(\d+) (.*)/) {
24*1f5207b7SJohn Levon            if (int($1) > 200) {
25*1f5207b7SJohn Levon                $too_common_funcs{$2} = 1;
26*1f5207b7SJohn Levon            }
27*1f5207b7SJohn Levon        }
28*1f5207b7SJohn Levon    }
29*1f5207b7SJohn Levon
30*1f5207b7SJohn Levon    close(FUNCS);
31*1f5207b7SJohn Levon
32*1f5207b7SJohn Levon    open(FILE, ">", "$path/../$project.common_functions");
33*1f5207b7SJohn Levon    foreach my $func (keys %too_common_funcs) {
34*1f5207b7SJohn Levon        if ($func =~ / /) {
35*1f5207b7SJohn Levon            next;
36*1f5207b7SJohn Levon        }
37*1f5207b7SJohn Levon        print FILE "$func\n";
38*1f5207b7SJohn Levon    }
39*1f5207b7SJohn Levon    close(FILE);
40*1f5207b7SJohn Levon}
41*1f5207b7SJohn Levon
42*1f5207b7SJohn Levonmy $exec_name = $0;
43*1f5207b7SJohn Levonmy $path = $exec_name;
44*1f5207b7SJohn Levon$path =~ s/(.*)\/.*/$1/;
45*1f5207b7SJohn Levonmy $project = shift;
46*1f5207b7SJohn Levonmy $warns = shift;
47*1f5207b7SJohn Levonmy $db_file = shift;
48*1f5207b7SJohn Levon
49*1f5207b7SJohn Levonif (!defined($db_file)) {
50*1f5207b7SJohn Levon    usage();
51*1f5207b7SJohn Levon}
52*1f5207b7SJohn Levon
53*1f5207b7SJohn Levonget_too_common_functions($path, $project, $warns);
54*1f5207b7SJohn Levon
55*1f5207b7SJohn Levonmy $db = DBI->connect("dbi:SQLite:$db_file", "", "", {AutoCommit => 0});
56*1f5207b7SJohn Levon$db->do("PRAGMA cache_size = 800000");
57*1f5207b7SJohn Levon$db->do("PRAGMA journal_mode = OFF");
58*1f5207b7SJohn Levon$db->do("PRAGMA count_changes = OFF");
59*1f5207b7SJohn Levon$db->do("PRAGMA temp_store = MEMORY");
60*1f5207b7SJohn Levon$db->do("PRAGMA locking = EXCLUSIVE");
61*1f5207b7SJohn Levon
62*1f5207b7SJohn Levonforeach my $func (keys %too_common_funcs) {
63*1f5207b7SJohn Levon    $db->do("insert into common_caller_info values ('unknown', 'too common', '$func', 0, 0, 0, -1, '', '');");
64*1f5207b7SJohn Levon}
65*1f5207b7SJohn Levon
66*1f5207b7SJohn Levonmy $call_id = 0;
67*1f5207b7SJohn Levonmy ($fn, $dummy, $sql);
68*1f5207b7SJohn Levon
69*1f5207b7SJohn Levonopen(WARNS, "<$warns");
70*1f5207b7SJohn Levonwhile (<WARNS>) {
71*1f5207b7SJohn Levon    # test.c:11 frob() SQL_caller_info: insert into caller_info values ('test.c', 'frob', '__smatch_buf_size', %CALL_ID%, 1, 0, -1, '', ');
72*1f5207b7SJohn Levon
73*1f5207b7SJohn Levon    if (!($_ =~ /^.*? \w+\(\) SQL_caller_info: /)) {
74*1f5207b7SJohn Levon        next;
75*1f5207b7SJohn Levon    }
76*1f5207b7SJohn Levon    ($dummy, $dummy, $dummy, $dummy, $dummy, $fn, $dummy) = split(/'/);
77*1f5207b7SJohn Levon
78*1f5207b7SJohn Levon    if ($fn =~ /__builtin_/) {
79*1f5207b7SJohn Levon        next;
80*1f5207b7SJohn Levon    }
81*1f5207b7SJohn Levon    if ($fn =~ /^(printk|memset|memcpy|kfree|printf|dev_err|writel)$/) {
82*1f5207b7SJohn Levon        next;
83*1f5207b7SJohn Levon    }
84*1f5207b7SJohn Levon
85*1f5207b7SJohn Levon    ($dummy, $dummy, $sql) = split(/:/, $_, 3);
86*1f5207b7SJohn Levon
87*1f5207b7SJohn Levon    if ($sql =~ /%call_marker%/) {
88*1f5207b7SJohn Levon        $sql =~ s/%call_marker%//; # don't need this taking space in the db.
89*1f5207b7SJohn Levon        $call_id++;
90*1f5207b7SJohn Levon    }
91*1f5207b7SJohn Levon    $sql =~ s/%CALL_ID%/$call_id/;
92*1f5207b7SJohn Levon
93*1f5207b7SJohn Levon    $db->do($sql);
94*1f5207b7SJohn Levon}
95*1f5207b7SJohn Levon$db->commit();
96*1f5207b7SJohn Levon$db->disconnect();
97