comparison: comparisons with 3 variables: "a > b + c"
[smatch.git] / smatch_data / db / smdb.py
blobd7e22b08eaaa9519c041a622324a5c19134977e0
1 #!/usr/bin/python
3 # Copyright (C) 2013 Oracle.
5 # Licensed under the Open Software License version 1.1
7 import sqlite3
8 import sys
9 import re
11 try:
12 con = sqlite3.connect('smatch_db.sqlite')
13 except sqlite3.Error, e:
14 print "Error %s:" % e.args[0]
15 sys.exit(1)
17 def usage():
18 print "%s <function> [table] [type] [parameter]" %(sys.argv[0])
19 sys.exit(1)
21 function_ptrs = []
22 searched_ptrs = []
23 def get_function_pointers_helper(func):
24 cur = con.cursor()
25 cur.execute("select distinct ptr from function_ptr where function = '%s';" %(func))
26 for row in cur:
27 ptr = row[0]
28 if ptr in function_ptrs:
29 continue
30 function_ptrs.append(ptr)
31 if not ptr in searched_ptrs:
32 searched_ptrs.append(ptr)
33 get_function_pointers_helper(ptr)
35 def get_function_pointers(func):
36 global function_ptrs
37 global searched_ptrs
38 function_ptrs = [func]
39 searched_ptrs = [func]
40 get_function_pointers_helper(func)
41 return function_ptrs
43 db_types = [ "INTERNAL", "PARAM_VALUE", "BUF_SIZE", "USER_DATA", "CAPPED_DATA",
44 "RETURN_VALUE", "DEREFERENCE", "RANGE_CAP", "LOCK_HELD",
45 "LOCK_RELEASED", "ABSOLUTE_LIMITS", "LIMITED_VALUE",
46 "ADDED_VALUE", "FILTER_VALUE", "PARAM_CLEARED",
47 "UPPER_CONSTRAINT" ]
49 def type_to_str(type_int):
51 t = int(type_int)
52 if t < len(db_types):
53 return db_types[t]
54 return type_int
56 def type_to_int(type_string):
57 for i in range(len(db_types)):
58 if db_types[i] == type_string:
59 return i
60 return -1
62 def display_caller_info(printed, cur):
63 for txt in cur:
64 if not printed:
65 print "file | caller | function | type | parameter | key | value |"
66 printed = 1
67 print "%20s | %20s | %20s |" %(txt[0], txt[1], txt[2]),
68 print " %10s |" %(type_to_str(txt[5])),
69 print " %d | %s | %s" %(txt[6], txt[7], txt[8])
70 return printed
72 def get_caller_info(ptrs, my_type):
73 cur = con.cursor()
74 printed = 0
75 type_filter = ""
76 if my_type != "":
77 type_filter = "and type = %d" %(type_to_int(my_type))
78 for ptr in ptrs:
79 cur.execute("select * from caller_info where function = '%s' %s;" %(ptr, type_filter))
80 printed = display_caller_info(printed, cur)
82 def print_caller_info(func, my_type = ""):
83 ptrs = get_function_pointers(func)
84 get_caller_info(ptrs, my_type)
86 def print_return_states(func):
87 cur = con.cursor()
88 cur.execute("select * from return_states where function = '%s';" %(func))
89 count = 0
90 for txt in cur:
91 printed = 1
92 if count == 0:
93 print "file | function | return_id | return_value | type | param | key | value |"
94 count += 1
95 print "%s | %s | %2s | %13s" %(txt[0], txt[1], txt[3], txt[4]),
96 print "| %13s |" %(type_to_str(txt[6])),
97 print " %2d | %20s | %20s |" %(txt[7], txt[8], txt[9])
99 def print_call_implies(func):
100 cur = con.cursor()
101 cur.execute("select * from call_implies where function = '%s';" %(func))
102 count = 0
103 for txt in cur:
104 if not count:
105 print "file | function | type | param | key | value |"
106 count += 1
107 print "%15s | %15s" %(txt[0], txt[1]),
108 print "| %15s" %(type_to_str(txt[4])),
109 print "| %3d | %15s |" %(txt[5], txt[6])
111 def print_type_size(var):
112 cur = con.cursor()
113 if not re.search("^\(struct ", var):
114 m = re.search('(?<=->)\w+', var)
115 print "searched"
116 if not m:
117 print "Can't determine type for %s" %(var)
118 return
119 var = "%->" + m.group(0)
120 cur.execute("select * from type_size where type like '%s';" %(var))
121 print "file | type | size"
122 for txt in cur:
123 printed = 1
124 print "%15s | %15s | %d" %(txt[0], txt[1], txt[2])
126 def print_fn_ptrs(func):
127 ptrs = get_function_pointers(func)
128 if not ptrs:
129 return
130 print "%s = " %(func),
131 i = 0
132 for p in ptrs:
133 if i > 0:
134 print ",",
135 i = i + 1
136 print "'%s'" %(p),
137 print ""
139 def get_callers(func):
140 ret = []
141 cur = con.cursor()
142 ptrs = get_function_pointers(func)
143 for ptr in ptrs:
144 cur.execute("select distinct caller from caller_info where function = '%s';" %(ptr))
145 for row in cur:
146 ret.append(row[0])
147 return ret
149 printed_funcs = []
150 def call_tree_helper(func, indent = 0):
151 global printed_funcs
152 if func in printed_funcs:
153 return
154 print "%s%s()" %(" " * indent, func)
155 if func == "too common":
156 return
157 if indent > 6:
158 return
159 printed_funcs.append(func)
160 callers = get_callers(func)
161 if len(callers) >= 20:
162 print "Over 20 callers for %s()" %(func)
163 return
164 for caller in callers:
165 call_tree_helper(caller, indent + 2)
167 def print_call_tree(func):
168 global printed_funcs
169 printed_funcs = []
170 call_tree_helper(func)
172 if len(sys.argv) < 2:
173 usage()
175 if len(sys.argv) == 2:
176 func = sys.argv[1]
177 print_caller_info(func)
178 elif sys.argv[1] == "user_data":
179 func = sys.argv[2]
180 print_caller_info(func, "USER_DATA")
181 elif sys.argv[1] == "param_value":
182 func = sys.argv[2]
183 print_caller_info(func, "PARAM_VALUE")
184 elif sys.argv[1] == "function_ptr" or sys.argv[1] == "fn_ptr":
185 func = sys.argv[2]
186 print_fn_ptrs(func)
187 elif sys.argv[1] == "return_states":
188 func = sys.argv[2]
189 print_return_states(func)
190 elif sys.argv[1] == "call_implies":
191 func = sys.argv[2]
192 print_call_implies(func)
193 elif sys.argv[1] == "type_size":
194 var = sys.argv[2]
195 print_type_size(var)
196 elif sys.argv[1] == "call_tree":
197 func = sys.argv[2]
198 print_call_tree(func)
199 else:
200 usage()