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 void remove_parens(char *str
)
42 while (*src
!= '\0') {
43 if (*src
== '(' || *src
== ')') {
52 struct smatch_state
*alloc_state_num(int num
)
54 struct smatch_state
*state
;
55 static char buff
[256];
57 state
= __alloc_smatch_state(0);
58 snprintf(buff
, 255, "%d", num
);
60 state
->name
= alloc_string(buff
);
61 state
->data
= INT_PTR(num
);
65 static void append(char *dest
, const char *data
, int buff_len
)
67 strncat(dest
, data
, buff_len
- strlen(dest
) - 1);
71 * If you have "foo(a, b, 1);" then use
72 * get_argument_from_call_expr(expr, 0) to return the expression for
73 * a. Yes, it does start counting from 0.
75 struct expression
*get_argument_from_call_expr(struct expression_list
*args
,
78 struct expression
*expr
;
84 FOR_EACH_PTR(args
, expr
) {
88 } END_FOR_EACH_PTR(expr
);
92 static struct expression
*get_array_expr(struct expression
*expr
)
96 if (expr
->type
!= EXPR_BINOP
|| expr
->op
!= '+')
99 type
= get_type(expr
->left
);
100 if (!type
|| type
->type
!= SYM_ARRAY
)
105 static void __get_variable_from_expr(struct symbol
**sym_ptr
, char *buf
,
106 struct expression
*expr
, int len
,
107 int *complicated
, int no_parens
)
109 struct expression
*tmp
;
111 switch (expr
->type
) {
117 __get_variable_from_expr(sym_ptr
, buf
, tmp
, len
, complicated
, no_parens
);
121 append(buf
, "->", len
);
123 append(buf
, ".", len
);
125 append(buf
, expr
->member
->name
, len
);
129 if (expr
->symbol_name
)
130 append(buf
, expr
->symbol_name
->name
, len
);
134 *sym_ptr
= expr
->symbol
;
140 if (get_expression_statement(expr
)) {
145 if (expr
->op
== '(') {
147 append(buf
, "(", len
);
148 } else if (expr
->op
!= '*' || !get_array_expr(expr
->unop
)) {
149 tmp
= show_special(expr
->op
);
150 append(buf
, tmp
, len
);
152 __get_variable_from_expr(sym_ptr
, buf
, expr
->unop
,
153 len
, complicated
, no_parens
);
155 if (expr
->op
== '(' && !no_parens
)
156 append(buf
, ")", len
);
158 if (expr
->op
== SPECIAL_DECREMENT
||
159 expr
->op
== SPECIAL_INCREMENT
||
168 __get_variable_from_expr(sym_ptr
, buf
, expr
->unop
,
169 len
, complicated
, no_parens
);
170 tmp
= show_special(expr
->op
);
171 append(buf
, tmp
, len
);
173 if (expr
->op
== SPECIAL_DECREMENT
|| expr
->op
== SPECIAL_INCREMENT
)
177 case EXPR_ASSIGNMENT
:
182 struct expression
*array_expr
;
185 array_expr
= get_array_expr(expr
);
187 __get_variable_from_expr(sym_ptr
, buf
, array_expr
, len
, complicated
, no_parens
);
188 append(buf
, "[", len
);
190 __get_variable_from_expr(sym_ptr
, buf
, expr
->left
, len
, complicated
, no_parens
);
191 snprintf(tmp
, sizeof(tmp
), " %s ", show_special(expr
->op
));
192 append(buf
, tmp
, len
);
194 __get_variable_from_expr(NULL
, buf
, expr
->right
, len
, complicated
, no_parens
);
196 append(buf
, "]", len
);
203 snprintf(tmp
, 25, "%lld", expr
->value
);
204 append(buf
, tmp
, len
);
208 append(buf
, "\"", len
);
209 append(buf
, expr
->string
->data
, len
);
210 append(buf
, "\"", len
);
213 struct expression
*tmp
;
217 __get_variable_from_expr(NULL
, buf
, expr
->fn
, len
, complicated
, no_parens
);
218 append(buf
, "(", len
);
220 FOR_EACH_PTR(expr
->args
, tmp
) {
222 append(buf
, ", ", len
);
223 __get_variable_from_expr(NULL
, buf
, tmp
, len
, complicated
, no_parens
);
224 } END_FOR_EACH_PTR(tmp
);
225 append(buf
, ")", len
);
229 __get_variable_from_expr(sym_ptr
, buf
,
230 expr
->cast_expression
, len
,
231 complicated
, no_parens
);
237 if (expr
->cast_type
&& get_base_type(expr
->cast_type
)) {
238 size
= (get_base_type(expr
->cast_type
))->bit_size
;
239 snprintf(tmp
, 25, "%d", bits_to_bytes(size
));
240 append(buf
, tmp
, len
);
246 //printf("unknown type = %d\n", expr->type);
252 * This is returns a stylized "c looking" representation of the
255 * It uses the same buffer every time so you have to save the result
256 * yourself if you want to keep it.
260 char *expr_to_str_sym(struct expression
*expr
, struct symbol
**sym_ptr
)
262 static char var_name
[VAR_LEN
];
271 __get_variable_from_expr(sym_ptr
, var_name
, expr
, sizeof(var_name
),
274 return alloc_string(var_name
);
279 char *expr_to_str(struct expression
*expr
)
281 return expr_to_str_sym(expr
, NULL
);
285 * get_variable_from_expr_simple() only returns simple variables.
286 * If it's a complicated variable like a->foo[x] instead of just 'a->foo'
287 * then it returns NULL.
289 char *expr_to_var_sym(struct expression
*expr
,
290 struct symbol
**sym_ptr
)
292 static char var_name
[VAR_LEN
];
301 expr
= strip_expr(expr
);
302 __get_variable_from_expr(sym_ptr
, var_name
, expr
, sizeof(var_name
),
310 return alloc_string(var_name
);
313 char *expr_to_var(struct expression
*expr
)
315 return expr_to_var_sym(expr
, NULL
);
318 int sym_name_is(const char *name
, struct expression
*expr
)
322 if (expr
->type
!= EXPR_SYMBOL
)
324 if (!strcmp(expr
->symbol_name
->name
, name
))
329 int is_zero(struct expression
*expr
)
333 if (get_value(expr
, &sval
) && sval
.value
== 0)
338 int is_array(struct expression
*expr
)
340 expr
= strip_expr(expr
);
341 if (!expr
|| expr
->type
!= EXPR_PREOP
|| expr
->op
!= '*')
349 struct expression
*get_array_name(struct expression
*expr
)
353 return strip_expr(expr
->unop
->left
);
356 struct expression
*get_array_offset(struct expression
*expr
)
360 return expr
->unop
->right
;
363 const char *show_state(struct smatch_state
*state
)
370 struct statement
*get_expression_statement(struct expression
*expr
)
372 /* What are those things called? if (({....; ret;})) { ...*/
374 if (expr
->type
!= EXPR_PREOP
)
378 if (expr
->unop
->type
!= EXPR_STATEMENT
)
380 if (expr
->unop
->statement
->type
!= STMT_COMPOUND
)
382 return expr
->unop
->statement
;
385 struct expression
*strip_parens(struct expression
*expr
)
390 if (expr
->type
== EXPR_PREOP
) {
391 if (expr
->op
== '(' && expr
->unop
->type
== EXPR_STATEMENT
&&
392 expr
->unop
->statement
->type
== STMT_COMPOUND
)
395 return strip_parens(expr
->unop
);
400 struct expression
*strip_expr(struct expression
*expr
)
405 switch (expr
->type
) {
406 case EXPR_FORCE_CAST
:
408 return strip_expr(expr
->cast_expression
);
410 if (expr
->op
== '(' && expr
->unop
->type
== EXPR_STATEMENT
&&
411 expr
->unop
->statement
->type
== STMT_COMPOUND
)
414 return strip_expr(expr
->unop
);
419 static void delete_state_tracker(struct tracker
*t
)
421 delete_state(t
->owner
, t
->name
, t
->sym
);
425 void scoped_state(int my_id
, const char *name
, struct symbol
*sym
)
429 t
= alloc_tracker(my_id
, name
, sym
);
430 add_scope_hook((scope_hook
*)&delete_state_tracker
, t
);
433 int is_error_return(struct expression
*expr
)
435 struct symbol
*cur_func
= cur_func_sym
;
440 if (cur_func
->type
!= SYM_NODE
)
442 cur_func
= get_base_type(cur_func
);
443 if (cur_func
->type
!= SYM_FN
)
445 cur_func
= get_base_type(cur_func
);
446 if (cur_func
== &void_ctype
)
448 if (!get_value(expr
, &sval
))
450 if (sval_cmp_val(sval
, 0) < 0)
452 if (cur_func
->type
== SYM_PTR
&& sval
.value
== 0)
457 int getting_address(void)
459 struct expression
*tmp
;
463 FOR_EACH_PTR_REVERSE(big_expression_stack
, tmp
) {
466 if (tmp
->type
== EXPR_PREOP
&& tmp
->op
== '(')
468 if (tmp
->op
== '.' && !dot_ops
++)
473 } END_FOR_EACH_PTR_REVERSE(tmp
);
477 char *get_member_name(struct expression
*expr
)
482 expr
= strip_expr(expr
);
483 if (expr
->type
!= EXPR_DEREF
)
485 sym
= get_type(expr
->deref
);
486 if (!sym
|| !sym
->ident
)
488 snprintf(buf
, sizeof(buf
), "(struct %s)->%s", sym
->ident
->name
, expr
->member
->name
);
489 return alloc_string(buf
);
492 int positions_eq(struct position pos1
, struct position pos2
)
494 if (pos1
.line
!= pos2
.line
)
496 if (pos1
.pos
!= pos2
.pos
)
498 if (pos1
.stream
!= pos2
.stream
)
503 struct statement
*get_current_statement(void)
505 struct statement
*prev
, *tmp
;
507 prev
= last_ptr_list((struct ptr_list
*)big_statement_stack
);
509 if (!prev
|| !get_macro_name(prev
->pos
))
512 FOR_EACH_PTR_REVERSE(big_statement_stack
, tmp
) {
513 if (positions_eq(tmp
->pos
, prev
->pos
))
515 if (prev
->pos
.line
> tmp
->pos
.line
)
518 } END_FOR_EACH_PTR_REVERSE(tmp
);
522 int get_param_num_from_sym(struct symbol
*sym
)
531 FOR_EACH_PTR(cur_func_sym
->ctype
.base_type
->arguments
, tmp
) {
535 } END_FOR_EACH_PTR(tmp
);
539 int ms_since(struct timeval
*start
)
544 gettimeofday(&end
, NULL
);
545 diff
= (end
.tv_sec
- start
->tv_sec
) * 1000.0;
546 diff
+= (end
.tv_usec
- start
->tv_usec
) / 1000.0;