2 * sparse/smatch_helper.c
4 * Copyright (C) 2006 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
11 * Miscellaneous helper functions.
21 char *alloc_string(const char *str
)
27 tmp
= malloc(strlen(str
) + 1);
32 void free_string(char *str
)
37 struct smatch_state
*alloc_state_num(int num
)
39 struct smatch_state
*state
;
40 static char buff
[256];
42 state
= __alloc_smatch_state(0);
43 snprintf(buff
, 255, "%d", num
);
45 state
->name
= alloc_string(buff
);
46 state
->data
= INT_PTR(num
);
50 static void append(char *dest
, const char *data
, int buff_len
)
52 strncat(dest
, data
, buff_len
- strlen(dest
) - 1);
56 * If you have "foo(a, b, 1);" then use
57 * get_argument_from_call_expr(expr, 0) to return the expression for
58 * a. Yes, it does start counting from 0.
60 struct expression
*get_argument_from_call_expr(struct expression_list
*args
,
63 struct expression
*expr
;
69 FOR_EACH_PTR(args
, expr
) {
73 } END_FOR_EACH_PTR(expr
);
77 static struct expression
*get_array_expr(struct expression
*expr
)
81 if (expr
->type
!= EXPR_BINOP
|| expr
->op
!= '+')
84 type
= get_type(expr
->left
);
85 if (!type
|| type
->type
!= SYM_ARRAY
)
90 static void __get_variable_from_expr(struct symbol
**sym_ptr
, char *buf
,
91 struct expression
*expr
, int len
,
94 struct expression
*tmp
;
102 __get_variable_from_expr(sym_ptr
, buf
, tmp
, len
, complicated
);
105 if (tmp
->op
== '*') {
106 append(buf
, "->", len
);
108 append(buf
, ".", len
);
110 append(buf
, expr
->member
->name
, len
);
114 if (expr
->symbol_name
)
115 append(buf
, expr
->symbol_name
->name
, len
);
119 *sym_ptr
= expr
->symbol
;
125 if (get_expression_statement(expr
)) {
130 if (expr
->op
!= '*' || !get_array_expr(expr
->unop
)) {
131 tmp
= show_special(expr
->op
);
132 append(buf
, tmp
, len
);
134 __get_variable_from_expr(sym_ptr
, buf
, expr
->unop
,
137 if (expr
->op
== '(') {
138 append(buf
, ")", len
);
141 if (expr
->op
== SPECIAL_DECREMENT
|| expr
->op
== SPECIAL_INCREMENT
)
149 __get_variable_from_expr(sym_ptr
, buf
, expr
->unop
,
151 tmp
= show_special(expr
->op
);
152 append(buf
, tmp
, len
);
154 if (expr
->op
== SPECIAL_DECREMENT
|| expr
->op
== SPECIAL_INCREMENT
)
160 struct expression
*array_expr
;
163 array_expr
= get_array_expr(expr
);
165 __get_variable_from_expr(sym_ptr
, buf
, array_expr
, len
, complicated
);
166 append(buf
, "[", len
);
168 __get_variable_from_expr(sym_ptr
, buf
, expr
->left
, len
,
170 snprintf(tmp
, sizeof(tmp
), " %s ", show_special(expr
->op
));
171 append(buf
, tmp
, len
);
173 __get_variable_from_expr(NULL
, buf
, expr
->right
,
176 append(buf
, "]", len
);
183 snprintf(tmp
, 25, "%lld", expr
->value
);
184 append(buf
, tmp
, len
);
188 append(buf
, "\"", len
);
189 append(buf
, expr
->string
->data
, len
);
190 append(buf
, "\"", len
);
193 struct expression
*tmp
;
197 __get_variable_from_expr(NULL
, buf
, expr
->fn
, len
,
199 append(buf
, "(", len
);
201 FOR_EACH_PTR_REVERSE(expr
->args
, tmp
) {
203 append(buf
, ", ", len
);
204 __get_variable_from_expr(NULL
, buf
, tmp
, len
,
206 } END_FOR_EACH_PTR_REVERSE(tmp
);
207 append(buf
, ")", len
);
211 __get_variable_from_expr(sym_ptr
, buf
,
212 expr
->cast_expression
, len
,
219 if (expr
->cast_type
&& get_base_type(expr
->cast_type
)) {
220 size
= (get_base_type(expr
->cast_type
))->bit_size
;
221 snprintf(tmp
, 25, "%d", size
);
222 append(buf
, tmp
, len
);
228 //printf("unknown type = %d\n", expr->type);
234 * This is returns a stylized "c looking" representation of the
237 * It uses the same buffer every time so you have to save the result
238 * yourself if you want to keep it.
242 char *get_variable_from_expr_complex(struct expression
*expr
, struct symbol
**sym_ptr
)
244 static char var_name
[VAR_LEN
];
253 __get_variable_from_expr(sym_ptr
, var_name
, expr
, sizeof(var_name
),
256 return alloc_string(var_name
);
262 * get_variable_from_expr_simple() only returns simple variables.
263 * If it's a complicated variable like a->foo instead of just 'a'
264 * then it returns NULL.
267 char *get_variable_from_expr(struct expression
*expr
,
268 struct symbol
**sym_ptr
)
270 static char var_name
[VAR_LEN
];
279 expr
= strip_expr(expr
);
280 __get_variable_from_expr(sym_ptr
, var_name
, expr
, sizeof(var_name
),
288 return alloc_string(var_name
);
291 int sym_name_is(const char *name
, struct expression
*expr
)
295 if (expr
->type
!= EXPR_SYMBOL
)
297 if (!strcmp(expr
->symbol_name
->name
, name
))
302 int is_zero(struct expression
*expr
)
306 if (get_value(expr
, &val
) && val
== 0)
311 int is_array(struct expression
*expr
)
313 expr
= strip_expr(expr
);
314 if (expr
->type
!= EXPR_PREOP
|| expr
->op
!= '*')
322 struct expression
*get_array_name(struct expression
*expr
)
326 return strip_expr(expr
->unop
->left
);
329 struct expression
*get_array_offset(struct expression
*expr
)
333 return expr
->unop
->right
;
336 const char *show_state(struct smatch_state
*state
)
343 struct statement
*get_expression_statement(struct expression
*expr
)
345 /* What are those things called? if (({....; ret;})) { ...*/
347 if (expr
->type
!= EXPR_PREOP
)
351 if (expr
->unop
->type
!= EXPR_STATEMENT
)
353 if (expr
->unop
->statement
->type
!= STMT_COMPOUND
)
355 return expr
->unop
->statement
;
358 struct expression
*strip_parens(struct expression
*expr
)
363 if (expr
->type
== EXPR_PREOP
) {
364 if (expr
->op
== '(' && expr
->unop
->type
== EXPR_STATEMENT
&&
365 expr
->unop
->statement
->type
== STMT_COMPOUND
)
368 return strip_parens(expr
->unop
);
373 struct expression
*strip_expr(struct expression
*expr
)
378 switch (expr
->type
) {
379 case EXPR_FORCE_CAST
:
381 return strip_expr(expr
->cast_expression
);
383 if (expr
->op
== '(' && expr
->unop
->type
== EXPR_STATEMENT
&&
384 expr
->unop
->statement
->type
== STMT_COMPOUND
)
387 return strip_expr(expr
->unop
);
392 static void delete_state_tracker(struct tracker
*t
)
394 delete_state(t
->owner
, t
->name
, t
->sym
);
398 void scoped_state(int my_id
, const char *name
, struct symbol
*sym
)
402 t
= alloc_tracker(my_id
, name
, sym
);
403 add_scope_hook((scope_hook
*)&delete_state_tracker
, t
);
406 int is_error_return(struct expression
*expr
)
408 struct symbol
*cur_func
= cur_func_sym
;
413 if (cur_func
->type
!= SYM_NODE
)
415 cur_func
= get_base_type(cur_func
);
416 if (cur_func
->type
!= SYM_FN
)
418 cur_func
= get_base_type(cur_func
);
419 if (cur_func
== &void_ctype
)
421 if (!get_value(expr
, &val
))
425 if (cur_func
->type
== SYM_PTR
&& val
== 0)
430 int getting_address(void)
432 struct expression
*tmp
;
436 FOR_EACH_PTR_REVERSE(big_expression_stack
, tmp
) {
439 if (tmp
->type
== EXPR_PREOP
&& tmp
->op
== '(')
441 if (tmp
->op
== '.' && !dot_ops
++)
446 } END_FOR_EACH_PTR_REVERSE(tmp
);
450 char *get_fnptr_name(struct expression
*expr
)
455 if (expr
->type
== EXPR_SYMBOL
)
456 return get_variable_from_expr(expr
, NULL
);
458 if (expr
->type
!= EXPR_DEREF
)
460 sym
= get_type(expr
->deref
);
461 if (!sym
|| !sym
->ident
)
463 snprintf(buf
, sizeof(buf
), "(struct %s)->%s", sym
->ident
->name
, expr
->member
->name
);
464 return alloc_string(buf
);