diff options
Diffstat (limited to 'pathologist/src/pathologist/edb_api.c')
-rw-r--r-- | pathologist/src/pathologist/edb_api.c | 368 |
1 files changed, 368 insertions, 0 deletions
diff --git a/pathologist/src/pathologist/edb_api.c b/pathologist/src/pathologist/edb_api.c new file mode 100644 index 0000000..5af26de --- /dev/null +++ b/pathologist/src/pathologist/edb_api.c | |||
@@ -0,0 +1,368 @@ | |||
1 | /** | ||
2 | * @file monkey/edb_api.c | ||
3 | * @brief Monkey API for accessing the Expression Database (edb) | ||
4 | */ | ||
5 | |||
6 | #include "monkey_common.h" | ||
7 | #include <stdlib.h> | ||
8 | #include <stdio.h> | ||
9 | #include <sqlite3.h> | ||
10 | #include "pathologist_edb.h" | ||
11 | |||
12 | |||
13 | /** | ||
14 | * Context for Database connection and Expressions | ||
15 | */ | ||
16 | struct MONKEY_EDB_Context | ||
17 | { | ||
18 | /** | ||
19 | * Database connection | ||
20 | */ | ||
21 | sqlite3 *db_handle; | ||
22 | }; | ||
23 | |||
24 | |||
25 | /** | ||
26 | * Establish a connection to the Expression Database | ||
27 | * | ||
28 | * @param db_file_name path the Expression Database file | ||
29 | * @return context to use for Accessing the Expression Database, NULL on error | ||
30 | */ | ||
31 | struct MONKEY_EDB_Context * | ||
32 | MONKEY_EDB_connect (const char *db_file_name) | ||
33 | { | ||
34 | int err; | ||
35 | struct MONKEY_EDB_Context *ctxt = | ||
36 | MONKEY_malloc (sizeof (struct MONKEY_EDB_Context)); | ||
37 | |||
38 | err = sqlite3_open (db_file_name, &ctxt->db_handle); | ||
39 | if (err) | ||
40 | { | ||
41 | fprintf(stderr, | ||
42 | "Cannot open Expression Database. `%s'\n", | ||
43 | sqlite3_errmsg (ctxt->db_handle)); | ||
44 | return NULL; | ||
45 | } | ||
46 | return ctxt; | ||
47 | } | ||
48 | |||
49 | |||
50 | /** | ||
51 | * Disconnect from Database, and cleanup resources | ||
52 | * | ||
53 | * @param context context containing the Expression Database handle | ||
54 | * @return MONKEY_OK on success, MONKEY_NO on failure | ||
55 | */ | ||
56 | int | ||
57 | MONKEY_EDB_disconnect (struct MONKEY_EDB_Context *cntxt) | ||
58 | { | ||
59 | sqlite3_close (cntxt->db_handle); | ||
60 | MONKEY_free (cntxt); | ||
61 | return MONKEY_OK; | ||
62 | } | ||
63 | |||
64 | |||
65 | |||
66 | int | ||
67 | MONKEY_EDB_get_file_names (struct MONKEY_EDB_Context *cntxt, | ||
68 | MONKEY_FileIterator iter, | ||
69 | void *iter_cls) | ||
70 | { | ||
71 | int err; | ||
72 | char *errMsg; | ||
73 | char *query; | ||
74 | |||
75 | if (MONKEY_asprintf (&query, "select distinct file_name from Expression") == -1) | ||
76 | { | ||
77 | fprintf(stderr, | ||
78 | "Memory allocation problem occurred during creating database query!\n"); | ||
79 | return MONKEY_NO; | ||
80 | } | ||
81 | |||
82 | err = sqlite3_exec (cntxt->db_handle, query, iter, iter_cls, &errMsg); | ||
83 | if (err) | ||
84 | { | ||
85 | fprintf(stderr, | ||
86 | "Error occurred while executing Database query. `%s'", | ||
87 | errMsg); | ||
88 | return MONKEY_NO; | ||
89 | } | ||
90 | return MONKEY_OK; | ||
91 | } | ||
92 | |||
93 | |||
94 | |||
95 | int | ||
96 | MONKEY_EDB_get_all_outer_scopes(struct MONKEY_EDB_Context | ||
97 | *cntxt, const char *file_name, | ||
98 | int function_beginning, | ||
99 | int scope_in_question_start, | ||
100 | int scope_in_question_end, | ||
101 | MONKEY_ExpressionIterator | ||
102 | iter, void *iter_cls) | ||
103 | { | ||
104 | int err; | ||
105 | char *errMsg; | ||
106 | char *query; | ||
107 | |||
108 | if (MONKEY_asprintf | ||
109 | (&query, | ||
110 | "select distinct end_lineno from Expression where file_name LIKE \'%%%s\' and start_lineno >= %d and start_lineno < %d and end_lineno > %d order by end_lineno", | ||
111 | file_name, function_beginning, scope_in_question_start, scope_in_question_end) == -1) | ||
112 | { | ||
113 | fprintf(stderr, | ||
114 | "Memory allocation problem occurred during creating database query!\n"); | ||
115 | return MONKEY_NO; | ||
116 | } | ||
117 | |||
118 | err = sqlite3_exec (cntxt->db_handle, query, iter, iter_cls, &errMsg); | ||
119 | if (err) | ||
120 | { | ||
121 | fprintf(stderr, | ||
122 | "Error occurred while executing Database query. `%s'", | ||
123 | errMsg); | ||
124 | return MONKEY_NO; | ||
125 | } | ||
126 | return MONKEY_OK; | ||
127 | } | ||
128 | |||
129 | int | ||
130 | MONKEY_EDB_expression_function_end_scope(struct MONKEY_EDB_Context | ||
131 | *cntxt, const char *file_name, | ||
132 | int start_lineno, | ||
133 | MONKEY_ExpressionIterator | ||
134 | iter, void *iter_cls) | ||
135 | { | ||
136 | int err; | ||
137 | char *errMsg; | ||
138 | char *query; | ||
139 | |||
140 | if (MONKEY_asprintf | ||
141 | (&query, | ||
142 | "select MAX(end_lineno) from Expression where file_name LIKE \'%%%s\' and start_lineno < %d and end_lineno != 32767", | ||
143 | file_name, start_lineno) == -1) | ||
144 | { | ||
145 | fprintf(stderr, | ||
146 | "Memory allocation problem occurred during creating database query!\n"); | ||
147 | return MONKEY_NO; | ||
148 | } | ||
149 | |||
150 | err = sqlite3_exec (cntxt->db_handle, query, iter, iter_cls, &errMsg); | ||
151 | if (err) | ||
152 | { | ||
153 | fprintf(stderr, | ||
154 | "Error occurred while executing Database query. `%s'", | ||
155 | errMsg); | ||
156 | return MONKEY_NO; | ||
157 | } | ||
158 | return MONKEY_OK; | ||
159 | } | ||
160 | |||
161 | int | ||
162 | MONKEY_EDB_function_start_line_for_scope(struct MONKEY_EDB_Context | ||
163 | *cntxt, const char *file_name, | ||
164 | int scope_end, | ||
165 | MONKEY_ExpressionIterator | ||
166 | iter, void *iter_cls) | ||
167 | { | ||
168 | int err; | ||
169 | char *errMsg; | ||
170 | char *query; | ||
171 | |||
172 | if (MONKEY_asprintf | ||
173 | (&query, | ||
174 | "select MIN(start_lineno) from Expression where file_name LIKE \'%%%s\' and end_lineno >= %d", | ||
175 | file_name, scope_end) == -1) | ||
176 | { | ||
177 | fprintf(stderr, | ||
178 | "Memory allocation problem occurred during creating database query!\n"); | ||
179 | return MONKEY_NO; | ||
180 | } | ||
181 | |||
182 | err = sqlite3_exec (cntxt->db_handle, query, iter, iter_cls, &errMsg); | ||
183 | if (err) | ||
184 | { | ||
185 | fprintf(stderr, | ||
186 | "Error occurred while executing Database query. `%s'", | ||
187 | errMsg); | ||
188 | return MONKEY_NO; | ||
189 | } | ||
190 | return MONKEY_OK; | ||
191 | } | ||
192 | |||
193 | |||
194 | /** | ||
195 | * Return the line number of the end-of-scope for the expression indicated by start_line_no | ||
196 | * | ||
197 | * @param cntxt context containing the Expression Database handle | ||
198 | * @param file_name path to the file in which the expression in question exists | ||
199 | * @param start_line_no expression's line | ||
200 | * @param iter callback function, iterator for values returned from the Database | ||
201 | * @param iter_cls closure for the expression iterator, will contain the scope-end line number | ||
202 | * @return MONKEY_OK on success, MONKEY_NO on failure | ||
203 | */ | ||
204 | int | ||
205 | MONKEY_EDB_get_expression_scope_end (struct MONKEY_EDB_Context | ||
206 | *cntxt, const char *file_name, | ||
207 | int start_line_no, | ||
208 | MONKEY_ExpressionIterator | ||
209 | iter, void *iter_cls) | ||
210 | { | ||
211 | int err; | ||
212 | char *errMsg; | ||
213 | char *query; | ||
214 | |||
215 | if (MONKEY_asprintf | ||
216 | (&query, | ||
217 | "select min(end_lineno) from Expression where file_name LIKE \'%%%s\' and start_lineno = %d", | ||
218 | file_name, start_line_no) == -1) | ||
219 | { | ||
220 | fprintf(stderr, | ||
221 | "Memory allocation problem occurred during creating database query!\n"); | ||
222 | return MONKEY_NO; | ||
223 | } | ||
224 | |||
225 | err = sqlite3_exec (cntxt->db_handle, query, iter, iter_cls, &errMsg); | ||
226 | MONKEY_free (query); | ||
227 | |||
228 | if (err) | ||
229 | { | ||
230 | fprintf(stderr, | ||
231 | "Error occurred while executing Database query. `%s'", | ||
232 | errMsg); | ||
233 | return MONKEY_NO; | ||
234 | } | ||
235 | return MONKEY_OK; | ||
236 | } | ||
237 | |||
238 | |||
239 | int | ||
240 | MONKEY_EDB_get_expression_scope_end_for_expression (struct MONKEY_EDB_Context | ||
241 | *cntxt, const char *file_name, | ||
242 | const char * expr_syntax, | ||
243 | MONKEY_ExpressionIterator | ||
244 | iter, void *iter_cls) | ||
245 | { | ||
246 | int err; | ||
247 | char *errMsg; | ||
248 | char *query; | ||
249 | |||
250 | if (MONKEY_asprintf | ||
251 | (&query, | ||
252 | "select end_lineno from Expression where file_name LIKE \'%%%s\' and expr_syntax = %s", | ||
253 | file_name, expr_syntax) == -1) | ||
254 | { | ||
255 | fprintf(stderr, | ||
256 | "Memory allocation problem occurred during creating database query!\n"); | ||
257 | return MONKEY_NO; | ||
258 | } | ||
259 | |||
260 | err = sqlite3_exec (cntxt->db_handle, query, iter, iter_cls, &errMsg); | ||
261 | MONKEY_free (query); | ||
262 | |||
263 | if (err) | ||
264 | { | ||
265 | fprintf(stderr, | ||
266 | "Error occurred while executing Database query. `%s'", | ||
267 | errMsg); | ||
268 | return MONKEY_NO; | ||
269 | } | ||
270 | return MONKEY_OK; | ||
271 | } | ||
272 | |||
273 | |||
274 | int | ||
275 | MONKEY_EDB_get_globals( struct MONKEY_EDB_Context *cntxt, | ||
276 | const char *file_names, | ||
277 | MONKEY_ExpressionIterator iter, | ||
278 | void *iter_cls) { | ||
279 | int ret = MONKEY_OK; | ||
280 | char *errMsg; | ||
281 | char *query; | ||
282 | if( MONKEY_asprintf(&query, | ||
283 | "SELECT DISTINCT expr_syntax, is_call FROM Expression WHERE (%s) AND start_lineno = 0 AND end_lineno = 32767", | ||
284 | file_names) == -1 ) { | ||
285 | fprintf(stderr, "Memory allocation problem occurred!\n"); | ||
286 | ret = MONKEY_NO; | ||
287 | goto fin; | ||
288 | } | ||
289 | |||
290 | if( sqlite3_exec (cntxt->db_handle, query, iter, iter_cls, &errMsg) ) { | ||
291 | fprintf(stderr, "Error occurred while executing Database query. `%s'", errMsg); | ||
292 | ret = MONKEY_NO; | ||
293 | goto fin; | ||
294 | } | ||
295 | fin: | ||
296 | MONKEY_free_non_null(query); | ||
297 | return MONKEY_NO; | ||
298 | } | ||
299 | |||
300 | /** | ||
301 | * Run an SQLite query to retrieve those expressions that are previous to | ||
302 | * given expression and are in the same function of the given expression | ||
303 | * | ||
304 | * @param cntxt context containing the Expression Database handle | ||
305 | * @param file_name path to the file in which the expression in question exists | ||
306 | * @param start_line_no expression beginning line | ||
307 | * @param iter callback function, iterator for expressions returned from the Database | ||
308 | * @param iter_cls closure for the expression iterator | ||
309 | * @return MONKEY_OK success, MONKEY_NO failure | ||
310 | */ | ||
311 | int | ||
312 | MONKEY_EDB_get_expressions (struct MONKEY_EDB_Context *cntxt, | ||
313 | const char *file_name, int start_line_no, | ||
314 | MONKEY_ExpressionIterator iter, | ||
315 | void *iter_cls) | ||
316 | { | ||
317 | int err; | ||
318 | char *errMsg; | ||
319 | char *query; | ||
320 | if (MONKEY_asprintf | ||
321 | (&query, | ||
322 | "select distinct expr_syntax, is_call from Expression where file_name LIKE \'%%%s\' and start_lineno <= %d and end_lineno >= %d and end_lineno != 32767", | ||
323 | file_name, start_line_no, start_line_no) == -1) | ||
324 | { | ||
325 | fprintf(stderr, "Memory allocation problem occurred!\n"); | ||
326 | return MONKEY_NO; | ||
327 | } | ||
328 | |||
329 | err = sqlite3_exec (cntxt->db_handle, query, iter, iter_cls, &errMsg); | ||
330 | if (err) | ||
331 | { | ||
332 | fprintf(stderr, "Error occurred while executing Database query. `%s'\n", errMsg); | ||
333 | return MONKEY_NO; | ||
334 | } | ||
335 | return MONKEY_OK; | ||
336 | } | ||
337 | |||
338 | |||
339 | int | ||
340 | MONKEY_EDB_get_sub_expressions (struct MONKEY_EDB_Context | ||
341 | *cntxt, const char *file_name, | ||
342 | int start_line_no, int end_line_no, | ||
343 | MONKEY_ExpressionIterator iter, | ||
344 | void *iter_cls) | ||
345 | { | ||
346 | int err; | ||
347 | char *errMsg; | ||
348 | char *query; | ||
349 | if (MONKEY_asprintf | ||
350 | (&query, | ||
351 | "select expr_syntax, start_lineno, is_call from Expression where file_name LIKE \'%%%s\' and start_lineno = %d and end_lineno = %d", | ||
352 | file_name, start_line_no, end_line_no) == -1) | ||
353 | { | ||
354 | fprintf(stderr, | ||
355 | "Memory allocation problem occurred!\n"); | ||
356 | return MONKEY_NO; | ||
357 | } | ||
358 | |||
359 | err = sqlite3_exec (cntxt->db_handle, query, iter, iter_cls, &errMsg); | ||
360 | if (err) | ||
361 | { | ||
362 | fprintf(stderr, | ||
363 | "Error occurred while executing Database query. `%s'", | ||
364 | errMsg); | ||
365 | return MONKEY_NO; | ||
366 | } | ||
367 | return MONKEY_OK; | ||
368 | } | ||