*new* smatch_scripts/follow_params.pl
[smatch.git] / smatch_db.c
blob7411bb99767b710ebdf66ab1576433fc29e945bd
1 /*
2 * smatch/smatch_db.c
4 * Copyright (C) 2010 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
8 */
10 #include <string.h>
11 #include <errno.h>
12 #include <sqlite3.h>
13 #include "smatch.h"
14 #include "smatch_slist.h"
15 #include "smatch_extra.h"
17 static sqlite3 *db;
19 struct def_callback {
20 int hook_type;
21 void (*callback)(const char *name, struct symbol *sym, char *value);
23 ALLOCATOR(def_callback, "definition db hook callbacks");
24 DECLARE_PTR_LIST(callback_list, struct def_callback);
25 static struct callback_list *callbacks;
27 void sql_exec(int (*callback)(void*, int, char**, char**), const char *sql)
29 char *err = NULL;
30 int rc;
32 if (option_no_db || !db)
33 return;
35 rc = sqlite3_exec(db, sql, callback, 0, &err);
36 if (rc != SQLITE_OK) {
37 fprintf(stderr, "SQL error #2: %s\n", err);
38 exit(1);
42 void add_definition_db_callback(void (*callback)(const char *name, struct symbol *sym, char *value), int type)
44 struct def_callback *def_callback = __alloc_def_callback(0);
46 def_callback->hook_type = type;
47 def_callback->callback = callback;
48 add_ptr_list(&callbacks, def_callback);
51 static unsigned long call_count;
52 static int db_count_callback(void *unused, int argc, char **argv, char **azColName)
54 call_count = strtoul(argv[0], NULL, 10);
55 return 0;
58 static int get_param(int param, char **name, struct symbol **sym)
60 struct symbol *arg;
61 int i;
63 i = 0;
64 FOR_EACH_PTR(cur_func_sym->ctype.base_type->arguments, arg) {
66 * this is a temporary hack to work around a bug (I think in sparse?)
67 * 2.6.37-rc1:fs/reiserfs/journal.o
68 * If there is a function definition without parameter name found
69 * after a function implementation then it causes a crash.
70 * int foo() {}
71 * int bar(char *);
73 if (arg->ident->name < (char *)100)
74 continue;
75 if (i == param && arg->ident->name) {
76 *name = arg->ident->name;
77 *sym = arg;
78 return TRUE;
80 i++;
81 } END_FOR_EACH_PTR(arg);
83 return FALSE;
86 static struct state_list *final_states;
87 static int prev_func_id = -1;
88 static int db_callback(void *unused, int argc, char **argv, char **azColName)
90 int func_id;
91 int type;
92 unsigned long param;
93 char *name;
94 struct symbol *sym;
95 struct def_callback *def_callback;
97 if (argc != 4)
98 return 0;
100 func_id = atoi(argv[0]);
101 type = atoi(argv[1]);
102 errno = 0;
103 param = strtoul(argv[2], NULL, 10);
104 if (errno)
105 return 0;
107 if (prev_func_id == -1)
108 prev_func_id = func_id;
109 if (func_id != prev_func_id) {
110 merge_slist(&final_states, __pop_fake_cur_slist());
111 __push_fake_cur_slist();
112 prev_func_id = func_id;
115 if (!get_param(param, &name, &sym))
116 return 0;
118 FOR_EACH_PTR(callbacks, def_callback) {
119 if (def_callback->hook_type == type)
120 def_callback->callback(name, sym, argv[3]);
121 } END_FOR_EACH_PTR(def_callback);
123 return 0;
126 static void match_data_from_db(struct symbol *sym)
128 char sql_filter[1024];
129 struct sm_state *sm;
131 if (!sym || !sym->ident || !sym->ident->name)
132 return;
134 if (sym->ctype.modifiers & MOD_STATIC) {
135 snprintf(sql_filter, 1024,
136 "file = '%s' and function = '%s' order by function_id desc;",
137 get_filename(), sym->ident->name);
138 } else {
139 snprintf(sql_filter, 1024,
140 "function = '%s' order by function_id desc;",
141 sym->ident->name);
144 call_count = 0;
145 run_sql(db_count_callback, "select count(*) from caller_info where %s",
146 sql_filter);
147 if (call_count == 0 || call_count > 20)
148 return;
150 prev_func_id = -1;
151 __push_fake_cur_slist();
152 run_sql(db_callback, "select function_id, type, parameter, value from caller_info"
153 " where %s", sql_filter);
154 merge_slist(&final_states, __pop_fake_cur_slist());
156 FOR_EACH_PTR(final_states, sm) {
157 __set_sm(sm);
158 } END_FOR_EACH_PTR(sm);
160 free_slist(&final_states);
163 void open_smatch_db(void)
165 #ifdef SQLITE_OPEN_READONLY
166 int rc;
168 if (option_no_db)
169 return;
171 rc = sqlite3_open_v2("smatch_db.sqlite", &db, SQLITE_OPEN_READONLY, NULL);
172 if (rc != SQLITE_OK) {
173 option_no_db = 1;
174 return;
176 return;
177 #else
178 option_no_db = 1;
179 return;
180 #endif
183 void register_definition_db_callbacks(int id)
185 #ifdef SQLITE_OPEN_READONLY
186 add_hook(&match_data_from_db, FUNC_DEF_HOOK);
187 #endif