2 * Copyright (C) 2006 Dan Carpenter.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
19 * Miscellaneous helper functions.
29 char *alloc_string(const char *str
)
35 tmp
= malloc(strlen(str
) + 1);
40 void free_string(char *str
)
45 void remove_parens(char *str
)
50 while (*src
!= '\0') {
51 if (*src
== '(' || *src
== ')') {
60 struct smatch_state
*alloc_state_num(int num
)
62 struct smatch_state
*state
;
63 static char buff
[256];
65 state
= __alloc_smatch_state(0);
66 snprintf(buff
, 255, "%d", num
);
68 state
->name
= alloc_string(buff
);
69 state
->data
= INT_PTR(num
);
73 void append(char *dest
, const char *data
, int buff_len
)
75 strncat(dest
, data
, buff_len
- strlen(dest
) - 1);
79 * If you have "foo(a, b, 1);" then use
80 * get_argument_from_call_expr(expr, 0) to return the expression for
81 * a. Yes, it does start counting from 0.
83 struct expression
*get_argument_from_call_expr(struct expression_list
*args
,
86 struct expression
*expr
;
92 FOR_EACH_PTR(args
, expr
) {
96 } END_FOR_EACH_PTR(expr
);
100 static struct expression
*get_array_expr(struct expression
*expr
)
104 if (expr
->type
!= EXPR_BINOP
|| expr
->op
!= '+')
107 type
= get_type(expr
->left
);
108 if (!type
|| type
->type
!= SYM_ARRAY
)
113 static void __get_variable_from_expr(struct symbol
**sym_ptr
, char *buf
,
114 struct expression
*expr
, int len
,
115 int *complicated
, int no_parens
)
117 struct expression
*tmp
;
119 switch (expr
->type
) {
125 __get_variable_from_expr(sym_ptr
, buf
, tmp
, len
, complicated
, no_parens
);
129 append(buf
, "->", len
);
131 append(buf
, ".", len
);
134 append(buf
, expr
->member
->name
, len
);
136 append(buf
, "unknown_member", len
);
140 if (expr
->symbol_name
)
141 append(buf
, expr
->symbol_name
->name
, len
);
145 *sym_ptr
= expr
->symbol
;
151 if (get_expression_statement(expr
)) {
156 if (expr
->op
== '(') {
158 append(buf
, "(", len
);
159 } else if (expr
->op
!= '*' || !get_array_expr(expr
->unop
)) {
160 tmp
= show_special(expr
->op
);
161 append(buf
, tmp
, len
);
163 __get_variable_from_expr(sym_ptr
, buf
, expr
->unop
,
164 len
, complicated
, no_parens
);
166 if (expr
->op
== '(' && !no_parens
)
167 append(buf
, ")", len
);
169 if (expr
->op
== SPECIAL_DECREMENT
||
170 expr
->op
== SPECIAL_INCREMENT
)
178 __get_variable_from_expr(sym_ptr
, buf
, expr
->unop
,
179 len
, complicated
, no_parens
);
180 tmp
= show_special(expr
->op
);
181 append(buf
, tmp
, len
);
183 if (expr
->op
== SPECIAL_DECREMENT
|| expr
->op
== SPECIAL_INCREMENT
)
187 case EXPR_ASSIGNMENT
:
192 struct expression
*array_expr
;
195 array_expr
= get_array_expr(expr
);
197 __get_variable_from_expr(sym_ptr
, buf
, array_expr
, len
, complicated
, no_parens
);
198 append(buf
, "[", len
);
200 __get_variable_from_expr(sym_ptr
, buf
, expr
->left
, len
, complicated
, no_parens
);
201 snprintf(tmp
, sizeof(tmp
), " %s ", show_special(expr
->op
));
202 append(buf
, tmp
, len
);
204 __get_variable_from_expr(NULL
, buf
, expr
->right
, len
, complicated
, no_parens
);
206 append(buf
, "]", len
);
213 snprintf(tmp
, 25, "%lld", expr
->value
);
214 append(buf
, tmp
, len
);
218 append(buf
, "\"", len
);
220 append(buf
, expr
->string
->data
, len
);
221 append(buf
, "\"", len
);
224 struct expression
*tmp
;
228 __get_variable_from_expr(NULL
, buf
, expr
->fn
, len
, complicated
, no_parens
);
229 append(buf
, "(", len
);
231 FOR_EACH_PTR(expr
->args
, tmp
) {
233 append(buf
, ", ", len
);
234 __get_variable_from_expr(NULL
, buf
, tmp
, len
, complicated
, no_parens
);
235 } END_FOR_EACH_PTR(tmp
);
236 append(buf
, ")", len
);
240 __get_variable_from_expr(sym_ptr
, buf
,
241 expr
->cast_expression
, len
,
242 complicated
, no_parens
);
248 if (expr
->cast_type
&& get_base_type(expr
->cast_type
)) {
249 size
= type_bytes(get_base_type(expr
->cast_type
));
250 snprintf(tmp
, 25, "%d", size
);
251 append(buf
, tmp
, len
);
255 case EXPR_IDENTIFIER
:
257 if (expr
->expr_ident
)
258 append(buf
, expr
->expr_ident
->name
, len
);
262 //printf("unknown type = %d\n", expr->type);
268 * This is returns a stylized "c looking" representation of the
271 * It uses the same buffer every time so you have to save the result
272 * yourself if you want to keep it.
276 char *expr_to_str_sym(struct expression
*expr
, struct symbol
**sym_ptr
)
278 static char var_name
[VAR_LEN
];
287 __get_variable_from_expr(sym_ptr
, var_name
, expr
, sizeof(var_name
),
290 return alloc_string(var_name
);
295 char *expr_to_str(struct expression
*expr
)
297 return expr_to_str_sym(expr
, NULL
);
301 * get_variable_from_expr_simple() only returns simple variables.
302 * If it's a complicated variable like a->foo[x] instead of just 'a->foo'
303 * then it returns NULL.
305 char *expr_to_var_sym(struct expression
*expr
,
306 struct symbol
**sym_ptr
)
308 static char var_name
[VAR_LEN
];
317 expr
= strip_expr(expr
);
318 __get_variable_from_expr(sym_ptr
, var_name
, expr
, sizeof(var_name
),
326 return alloc_string(var_name
);
329 char *expr_to_var(struct expression
*expr
)
331 return expr_to_var_sym(expr
, NULL
);
334 int sym_name_is(const char *name
, struct expression
*expr
)
338 if (expr
->type
!= EXPR_SYMBOL
)
340 if (!strcmp(expr
->symbol_name
->name
, name
))
345 int is_zero(struct expression
*expr
)
349 if (get_value(expr
, &sval
) && sval
.value
== 0)
354 int is_array(struct expression
*expr
)
356 expr
= strip_expr(expr
);
357 if (!expr
|| expr
->type
!= EXPR_PREOP
|| expr
->op
!= '*')
365 struct expression
*get_array_name(struct expression
*expr
)
369 return strip_expr(expr
->unop
->left
);
372 struct expression
*get_array_offset(struct expression
*expr
)
376 return expr
->unop
->right
;
379 const char *show_state(struct smatch_state
*state
)
386 struct statement
*get_expression_statement(struct expression
*expr
)
388 /* What are those things called? if (({....; ret;})) { ...*/
390 if (expr
->type
!= EXPR_PREOP
)
394 if (expr
->unop
->type
!= EXPR_STATEMENT
)
396 if (expr
->unop
->statement
->type
!= STMT_COMPOUND
)
398 return expr
->unop
->statement
;
401 struct expression
*strip_parens(struct expression
*expr
)
406 if (expr
->type
== EXPR_PREOP
) {
407 if (expr
->op
== '(' && expr
->unop
->type
== EXPR_STATEMENT
&&
408 expr
->unop
->statement
->type
== STMT_COMPOUND
)
411 return strip_parens(expr
->unop
);
416 struct expression
*strip_expr(struct expression
*expr
)
421 switch (expr
->type
) {
422 case EXPR_FORCE_CAST
:
424 return strip_expr(expr
->cast_expression
);
426 if (expr
->op
== '(' && expr
->unop
->type
== EXPR_STATEMENT
&&
427 expr
->unop
->statement
->type
== STMT_COMPOUND
)
430 return strip_expr(expr
->unop
);
432 case EXPR_CONDITIONAL
:
433 if (known_condition_true(expr
->conditional
)) {
435 return strip_expr(expr
->cond_true
);
436 return strip_expr(expr
->conditional
);
438 if (known_condition_false(expr
->conditional
))
439 return strip_expr(expr
->cond_false
);
442 if (sym_name_is("__builtin_expect", expr
->fn
)) {
443 expr
= get_argument_from_call_expr(expr
->args
, 0);
444 return strip_expr(expr
);
451 static void delete_state_tracker(struct tracker
*t
)
453 delete_state(t
->owner
, t
->name
, t
->sym
);
457 void scoped_state(int my_id
, const char *name
, struct symbol
*sym
)
461 t
= alloc_tracker(my_id
, name
, sym
);
462 add_scope_hook((scope_hook
*)&delete_state_tracker
, t
);
465 int is_error_return(struct expression
*expr
)
467 struct symbol
*cur_func
= cur_func_sym
;
472 if (cur_func
->type
!= SYM_NODE
)
474 cur_func
= get_base_type(cur_func
);
475 if (cur_func
->type
!= SYM_FN
)
477 cur_func
= get_base_type(cur_func
);
478 if (cur_func
== &void_ctype
)
480 if (!get_implied_value(expr
, &sval
))
484 if (cur_func
->type
== SYM_PTR
&& sval
.value
== 0)
489 int getting_address(void)
491 struct expression
*tmp
;
495 FOR_EACH_PTR_REVERSE(big_expression_stack
, tmp
) {
498 if (tmp
->type
== EXPR_PREOP
&& tmp
->op
== '(')
500 if (tmp
->op
== '.' && !dot_ops
++)
505 } END_FOR_EACH_PTR_REVERSE(tmp
);
509 char *get_member_name(struct expression
*expr
)
514 expr
= strip_expr(expr
);
515 if (expr
->type
!= EXPR_DEREF
)
517 sym
= get_type(expr
->deref
);
520 /* FIXME: HACK! Sparse isn't storing the names of unions... Just take last member */
521 if (sym
->type
== SYM_UNION
) {
524 FOR_EACH_PTR_REVERSE(sym
->symbol_list
, tmp
) {
526 const char *member_name
;
529 member_name
= expr
->member
->name
;
531 member_name
= "unknown_member";
532 snprintf(buf
, sizeof(buf
), "(union hack %s)->%s", tmp
->ident
->name
, member_name
);
533 return alloc_string(buf
);
535 } END_FOR_EACH_PTR_REVERSE(tmp
);
538 if (!sym
->ident
|| !expr
->member
)
540 snprintf(buf
, sizeof(buf
), "(struct %s)->%s", sym
->ident
->name
, expr
->member
->name
);
541 return alloc_string(buf
);
544 int cmp_pos(struct position pos1
, struct position pos2
)
546 /* the stream position is ... */
547 if (pos1
.stream
> pos2
.stream
)
549 if (pos1
.stream
< pos2
.stream
)
552 if (pos1
.line
< pos2
.line
)
554 if (pos1
.line
> pos2
.line
)
557 if (pos1
.pos
< pos2
.pos
)
559 if (pos1
.pos
> pos2
.pos
)
565 int positions_eq(struct position pos1
, struct position pos2
)
567 if (pos1
.line
!= pos2
.line
)
569 if (pos1
.pos
!= pos2
.pos
)
571 if (pos1
.stream
!= pos2
.stream
)
576 struct statement
*get_current_statement(void)
578 struct statement
*prev
, *tmp
;
580 prev
= last_ptr_list((struct ptr_list
*)big_statement_stack
);
582 if (!prev
|| !get_macro_name(prev
->pos
))
585 FOR_EACH_PTR_REVERSE(big_statement_stack
, tmp
) {
586 if (positions_eq(tmp
->pos
, prev
->pos
))
588 if (prev
->pos
.line
> tmp
->pos
.line
)
591 } END_FOR_EACH_PTR_REVERSE(tmp
);
595 struct statement
*get_prev_statement(void)
597 struct statement
*tmp
;
601 FOR_EACH_PTR_REVERSE(big_statement_stack
, tmp
) {
604 } END_FOR_EACH_PTR_REVERSE(tmp
);
608 int get_param_num_from_sym(struct symbol
*sym
)
617 FOR_EACH_PTR(cur_func_sym
->ctype
.base_type
->arguments
, tmp
) {
621 } END_FOR_EACH_PTR(tmp
);
625 int get_param_num(struct expression
*expr
)
632 name
= expr_to_var_sym(expr
, &sym
);
636 return get_param_num_from_sym(sym
);
639 int ms_since(struct timeval
*start
)
644 gettimeofday(&end
, NULL
);
645 diff
= (end
.tv_sec
- start
->tv_sec
) * 1000.0;
646 diff
+= (end
.tv_usec
- start
->tv_usec
) / 1000.0;
650 int parent_is_gone_var_sym(const char *name
, struct symbol
*sym
)
655 if (parent_is_null_var_sym(name
, sym
) ||
656 parent_is_free_var_sym(name
, sym
))
661 int parent_is_gone(struct expression
*expr
)
667 expr
= strip_expr(expr
);
668 var
= expr_to_var_sym(expr
, &sym
);
671 ret
= parent_is_gone_var_sym(var
, sym
);