make function declaration static
[smatch.git] / smatch_helper.c
blob8d3a206c8210c1f8009c2133b27fb7f639d7b95a
1 /*
2 * sparse/smatch_helper.c
4 * Copyright (C) 2006 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
8 */
11 * Miscellaneous helper functions.
14 #include <stdlib.h>
15 #include <stdio.h>
16 #include "allocate.h"
17 #include "smatch.h"
19 #define VAR_LEN 512
22 char *alloc_string(const char *str)
24 char *tmp;
26 if (!str)
27 return NULL;
28 tmp = malloc(strlen(str) + 1);
29 strcpy(tmp, str);
30 return tmp;
33 void free_string(char *str)
35 free(str);
38 static void append(char *dest, const char *data, int buff_len)
40 strncat(dest, data, buff_len - strlen(dest) - 1);
44 * If you have "foo(a, b, 1);" then use
45 * get_argument_from_call_expr(expr, 0) to return the expression for
46 * a. Yes, it does start counting from 0.
48 struct expression *get_argument_from_call_expr(struct expression_list *args,
49 int num)
51 struct expression *expr;
52 int i = 0;
54 if (!args)
55 return NULL;
57 FOR_EACH_PTR(args, expr) {
58 if (i == num)
59 return expr;
60 i++;
61 } END_FOR_EACH_PTR(expr);
62 return NULL;
65 static void __get_variable_from_expr(struct symbol **sym_ptr, char *buf,
66 struct expression *expr, int len,
67 int *complicated)
69 struct expression *tmp;
71 switch(expr->type) {
72 case EXPR_DEREF:
73 tmp = expr->deref;
74 if (!strcmp(show_special(tmp->op), "*")) {
75 tmp = tmp->unop;
77 __get_variable_from_expr(sym_ptr, buf, tmp, len, complicated);
79 tmp = expr->deref;
80 if (!strcmp(show_special(tmp->op), "*")) {
81 append(buf, "->", len);
82 } else {
83 append(buf, ".", len);
85 append(buf, expr->member->name, len);
87 return;
88 case EXPR_SYMBOL:
89 if (expr->symbol_name)
90 append(buf, expr->symbol_name->name, len);
91 if (sym_ptr) {
92 if (*sym_ptr)
93 *complicated = 1;
94 *sym_ptr = expr->symbol;
96 return;
97 case EXPR_PREOP: {
98 const char *tmp;
100 if (get_block_thing(expr)) {
101 *complicated = 2;
102 return;
106 tmp = show_special(expr->op);
107 append(buf, tmp, len);
108 __get_variable_from_expr(sym_ptr, buf, expr->unop,
109 len, complicated);
111 if (tmp[0] == '(') {
112 append(buf, ")", len);
115 if ((!strcmp(tmp, "--")) || (!strcmp(tmp, "++")))
116 *complicated = 1;
118 return;
120 case EXPR_POSTOP: {
121 const char *tmp;
123 __get_variable_from_expr(sym_ptr, buf, expr->unop,
124 len, complicated);
125 tmp = show_special(expr->op);
126 append(buf, tmp, len);
128 if ((!strcmp(tmp, "--")) || (!strcmp(tmp, "++")))
129 *complicated = 1;
131 return;
133 case EXPR_BINOP: {
134 const char *tmp;
136 *complicated = 1;
137 append(buf, "(", len);
138 __get_variable_from_expr(NULL, buf, expr->left, len,
139 complicated);
140 tmp = show_special(expr->op);
141 append(buf, tmp, len);
142 __get_variable_from_expr(sym_ptr, buf, expr->right,
143 len, complicated);
144 append(buf, ")", len);
145 return;
147 case EXPR_VALUE: {
148 char tmp[25];
150 snprintf(tmp, 25, "%lld", expr->value);
151 append(buf, tmp, len);
152 return;
154 case EXPR_STRING:
155 append(buf, expr->string->data, len);
156 return;
157 case EXPR_CALL: {
158 struct expression *tmp;
159 int i;
161 *complicated = 1;
162 __get_variable_from_expr(NULL, buf, expr->fn, len,
163 complicated);
164 append(buf, "(", len);
165 i = 0;
166 FOR_EACH_PTR_REVERSE(expr->args, tmp) {
167 if (i++)
168 append(buf, ", ", len);
169 __get_variable_from_expr(NULL, buf, tmp, len,
170 complicated);
171 } END_FOR_EACH_PTR_REVERSE(tmp);
172 append(buf, ")", len);
173 return;
175 case EXPR_CAST:
176 __get_variable_from_expr(sym_ptr, buf,
177 expr->cast_expression, len,
178 complicated);
179 return;
180 case EXPR_SIZEOF: {
181 int size;
182 char tmp[25];
184 if (expr->cast_type && get_base_type(expr->cast_type)) {
185 size = (get_base_type(expr->cast_type))->bit_size;
186 snprintf(tmp, 25, "%d", size);
187 append(buf, tmp, len);
189 return;
191 default:
192 *complicated = 1;
193 //printf("unknown type = %d\n", expr->type);
194 return;
200 * This is returns a stylized "c looking" representation of the
201 * variable name.
203 * It uses the same buffer every time so you have to save the result
204 * yourself if you want to keep it.
208 char *get_variable_from_expr_complex(struct expression *expr, struct symbol **sym_ptr)
210 static char var_name[VAR_LEN];
211 int complicated = 0;
213 if (sym_ptr)
214 *sym_ptr = NULL;
215 var_name[0] = '\0';
217 if (!expr)
218 return NULL;
219 __get_variable_from_expr(sym_ptr, var_name, expr, sizeof(var_name),
220 &complicated);
221 if (complicated < 2)
222 return alloc_string(var_name);
223 else
224 return NULL;
228 * get_variable_from_expr_simple() only returns simple variables.
229 * If it's a complicated variable like a->foo instead of just 'a'
230 * then it returns NULL.
233 char *get_variable_from_expr(struct expression *expr,
234 struct symbol **sym_ptr)
236 static char var_name[VAR_LEN];
237 int complicated = 0;
239 if (sym_ptr)
240 *sym_ptr = NULL;
241 var_name[0] = '\0';
243 if (!expr)
244 return NULL;
245 expr = strip_expr(expr);
246 __get_variable_from_expr(sym_ptr, var_name, expr, sizeof(var_name),
247 &complicated);
249 if (complicated) {
250 if (sym_ptr)
251 *sym_ptr = NULL;
252 return NULL;
254 return alloc_string(var_name);
257 struct symbol *get_ptr_type_ptr(struct symbol *sym)
259 if (!sym) {
260 return NULL;
263 if (sym->type != SYM_NODE)
264 return NULL;
265 sym = get_base_type(sym);
266 if (sym->type != SYM_PTR)
267 return NULL;
268 sym = get_base_type(sym);
269 return sym;
272 static struct symbol *get_struct_sym(struct expression *expr)
274 struct symbol *base_type;
275 struct symbol *parent_struct;
276 struct symbol *tmp;
278 if (expr->type != EXPR_PREOP)
279 return NULL;
281 expr = expr->unop;
282 if (expr->type == EXPR_DEREF) {
283 parent_struct = get_struct_sym(expr->deref);
284 if (!parent_struct)
285 return NULL;
286 tmp = NULL;
287 FOR_EACH_PTR(parent_struct->symbol_list, tmp) {
288 if (tmp->ident == expr->member)
289 break;
290 } END_FOR_EACH_PTR(tmp);
291 if (!tmp || tmp->ident != expr->member)
292 return NULL;
293 base_type = get_base_type(tmp);
294 } else if (expr->type == EXPR_SYMBOL) {
295 base_type = get_base_type(expr->symbol);
296 } else {
297 return NULL;
299 if (base_type->type != SYM_PTR)
300 return NULL;
301 base_type = get_base_type(base_type);
302 if (base_type->type != SYM_STRUCT && base_type->type != SYM_UNION)
303 return NULL;
304 return base_type;
307 struct symbol *get_deref_type(struct expression *expr)
309 struct ident *member = expr->member;
310 struct symbol *struct_sym;
311 struct symbol *tmp;
313 struct_sym = get_struct_sym(expr->deref);
314 if (!struct_sym || (struct_sym->type != SYM_STRUCT
315 && struct_sym->type != SYM_UNION))
316 return NULL;
317 FOR_EACH_PTR(struct_sym->symbol_list, tmp) {
318 if (tmp->ident == member)
319 return get_ptr_type_ptr(tmp);
320 } END_FOR_EACH_PTR(tmp);
321 return NULL;
324 struct symbol *get_ptr_type(struct expression *expr)
326 struct symbol *ptr_type = NULL;
328 if (!expr)
329 return NULL;
330 if (expr->type == EXPR_DEREF)
331 ptr_type = get_deref_type(expr);
332 if (expr->type == EXPR_SYMBOL)
333 ptr_type = get_ptr_type_ptr(expr->symbol);
334 return ptr_type;
337 int sym_name_is(const char *name, struct expression *expr)
339 if (!expr)
340 return 0;
341 if (expr->type != EXPR_SYMBOL)
342 return 0;
343 if (!strcmp(expr->symbol_name->name, name))
344 return 1;
345 return 0;
348 #define NOTIMPLIED 0
349 #define IMPLIED 1
351 static int _get_value(struct expression *expr, int *discard, int implied)
353 int dis = 0;
354 int ret = UNDEFINED;
356 if (!expr)
357 return UNDEFINED;
358 if (!discard)
359 discard = &dis;
360 if (*discard)
361 return UNDEFINED;
363 expr = strip_expr(expr);
365 switch (expr->type){
366 case EXPR_VALUE:
367 ret = expr->value;
368 break;
369 case EXPR_PREOP:
370 if (!strcmp("-", show_special(expr->op)))
371 ret = - _get_value(expr->unop, discard, implied);
372 else
373 *discard = 1;
374 break;
375 case EXPR_BINOP: {
376 int left, right;
378 if (!show_special(expr->op)) {
379 *discard = 1;
380 break;
382 left = _get_value(expr->left, discard, implied);
383 right = _get_value(expr->right, discard, implied);
384 if (!strcmp("*", show_special(expr->op))) {
385 ret = left * right;
386 } else if (!strcmp("/", show_special(expr->op))) {
387 ret = left / right;
388 } else if (!strcmp("+", show_special(expr->op))) {
389 ret = left + right;
390 } else if (!strcmp("-", show_special(expr->op))) {
391 ret = left - right;
392 } else if (!strcmp("|", show_special(expr->op))) {
393 ret = left | right;
394 } else if (!strcmp("&", show_special(expr->op))) {
395 ret = left & right;
396 } else if (!strcmp(">>", show_special(expr->op))) {
397 ret = left >> right;
398 } else if (!strcmp("<<", show_special(expr->op))) {
399 ret = left << right;
400 } else {
401 *discard = 1;
403 break;
405 case EXPR_PTRSIZEOF:
406 case EXPR_SIZEOF:
407 ret = get_expression_value(expr);
408 break;
409 default:
410 if (implied) {
411 ret = get_implied_single_val(expr);
412 if (ret == UNDEFINED)
413 *discard = 1;
414 } else {
415 *discard = 1;
418 if (*discard)
419 return UNDEFINED;
420 return ret;
423 /* returns UNDEFINED on error */
424 int get_value(struct expression *expr)
426 return _get_value(expr, NULL, NOTIMPLIED);
429 int get_implied_value(struct expression *expr)
431 return _get_value(expr, NULL, IMPLIED);
434 int is_zero(struct expression *expr)
436 if (get_value(expr) == 0)
437 return 1;
438 return 0;
441 int is_array(struct expression *expr)
443 expr = strip_expr(expr);
444 if (expr->type != EXPR_PREOP || strcmp(show_special(expr->op), "*"))
445 return 0;
446 expr = expr->unop;
447 if (strcmp(show_special(expr->op), "+"))
448 return 0;
449 return 1;
452 struct expression *get_array_name(struct expression *expr)
454 if (!is_array(expr))
455 return NULL;
456 return expr->unop->left;
459 struct expression *get_array_offset(struct expression *expr)
461 if (!is_array(expr))
462 return NULL;
463 return expr->unop->right;
466 const char *show_state(struct smatch_state *state)
468 if (!state)
469 return NULL;
470 return state->name;
473 struct statement *get_block_thing(struct expression *expr)
475 /* What are those things called? if (({....; ret;})) { ...*/
477 if (expr->type != EXPR_PREOP)
478 return NULL;
479 if (expr->op != '(')
480 return NULL;
481 if (expr->unop->type != EXPR_STATEMENT)
482 return NULL;
483 if (expr->unop->statement->type != STMT_COMPOUND)
484 return NULL;
485 return expr->unop->statement;
488 struct expression *strip_expr(struct expression *expr)
490 if (!expr)
491 return NULL;
493 switch(expr->type) {
494 case EXPR_CAST:
495 return strip_expr(expr->cast_expression);
496 case EXPR_PREOP:
497 if (expr->op == '(' && expr->unop->type == EXPR_STATEMENT &&
498 expr->unop->statement->type == STMT_COMPOUND)
499 return expr;
500 if (expr->op == '(')
501 return strip_expr(expr->unop);
503 return expr;
506 static void delete_state_tracker(struct tracker *t)
508 delete_state(t->owner, t->name, t->sym);
509 __free_tracker(t);
512 void scoped_state(const char *name, int my_id, struct symbol *sym)
514 struct tracker *t;
516 t = alloc_tracker(my_id, name, sym);
517 add_scope_hook((scope_hook *)&delete_state_tracker, t);