2 * sparse/smatch_helper.c
4 * Copyright (C) 2006 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
15 static int star_count
;
19 char *alloc_string(const char *str
)
25 tmp
= malloc(strlen(str
) + 1);
30 void free_string(char *str
)
35 static void prepend(char *dest
, const char *data
, int buff_len
)
40 space_needed
= strlen(data
);
41 for (i
= buff_len
- space_needed
- 1; i
>= 0 ; i
--)
42 dest
[i
+ space_needed
] = dest
[i
];
43 for (i
= 0; i
< space_needed
% buff_len
; i
++)
45 dest
[buff_len
- 1] = '\0';
49 * If you have "foo(a, b, 1);" then use
50 * get_argument_from_call_expr(expr, 0) to return the expression for
51 * a. Yes, it does start counting from 0.
53 struct expression
*get_argument_from_call_expr(struct expression_list
*args
,
56 struct expression
*expr
;
62 FOR_EACH_PTR(args
, expr
) {
66 } END_FOR_EACH_PTR(expr
);
70 static void __get_variable_from_expr(struct symbol
**sym_ptr
, char *buf
,
71 struct expression
*expr
, int len
,
76 prepend(buf
, expr
->member
->name
, len
);
77 if (!strcmp(show_special(expr
->deref
->op
), "*"))
78 prepend(buf
, "->", len
);
80 prepend(buf
, ".", len
);
82 //printf("debug: %d\n", expr->deref
84 __get_variable_from_expr(sym_ptr
, buf
, expr
->deref
,
88 if (expr
->symbol_name
)
89 prepend(buf
, expr
->symbol_name
->name
, len
);
93 *sym_ptr
= expr
->symbol
;
99 if (get_block_thing(expr
)) {
107 __get_variable_from_expr(sym_ptr
, buf
, expr
->unop
,
109 tmp
= show_special(expr
->op
);
111 if (star_count
-- >= 0) {
112 prepend(buf
, tmp
, len
);
115 prepend(buf
, tmp
, len
);
119 strncat(buf
, ")", len
- strlen(buf
));
123 if ((!strcmp(tmp
, "--")) || (!strcmp(tmp
, "++")))
131 tmp
= show_special(expr
->op
);
132 prepend(buf
, tmp
, len
);
133 __get_variable_from_expr(sym_ptr
, buf
, expr
->unop
,
136 if ((!strcmp(tmp
, "--")) || (!strcmp(tmp
, "++")))
145 prepend(buf
, ")", len
);
146 __get_variable_from_expr(NULL
, buf
, expr
->right
, len
,
148 tmp
= show_special(expr
->op
);
149 prepend(buf
, tmp
, len
);
150 __get_variable_from_expr(sym_ptr
, buf
, expr
->left
,
152 prepend(buf
, "(", len
);
158 snprintf(tmp
, 25, "%lld", expr
->value
);
159 prepend(buf
, tmp
, len
);
163 prepend(buf
, expr
->string
->data
, len
);
166 struct expression
*tmp
;
170 prepend(buf
, ")", len
);
171 FOR_EACH_PTR_REVERSE(expr
->args
, tmp
) {
173 prepend(buf
, ", ", len
);
174 __get_variable_from_expr(NULL
, buf
, tmp
, len
,
176 } END_FOR_EACH_PTR_REVERSE(tmp
);
177 prepend(buf
, "(", len
);
178 __get_variable_from_expr(NULL
, buf
, expr
->fn
, len
,
183 __get_variable_from_expr(sym_ptr
, buf
,
184 expr
->cast_expression
, len
,
191 if (expr
->cast_type
&& get_base_type(expr
->cast_type
)) {
192 size
= (get_base_type(expr
->cast_type
))->bit_size
;
193 snprintf(tmp
, 25, "%d", size
);
194 prepend(buf
, tmp
, len
);
200 //printf("unknown type = %d\n", expr->type);
207 * This is returns a stylized "c looking" representation of the
210 * It uses the same buffer every time so you have to save the result
211 * yourself if you want to keep it.
215 char *get_variable_from_expr_complex(struct expression
*expr
, struct symbol
**sym_ptr
)
217 static char var_name
[VAR_LEN
];
227 __get_variable_from_expr(sym_ptr
, var_name
, expr
, sizeof(var_name
),
230 return alloc_string(var_name
);
236 * get_variable_from_expr_simple() only returns simple variables.
237 * If it's a complicated variable like a->foo instead of just 'a'
238 * then it returns NULL.
241 char *get_variable_from_expr(struct expression
*expr
,
242 struct symbol
**sym_ptr
)
244 static char var_name
[VAR_LEN
];
254 expr
= strip_expr(expr
);
255 __get_variable_from_expr(sym_ptr
, var_name
, expr
, sizeof(var_name
),
263 return alloc_string(var_name
);
266 struct symbol
*get_ptr_type_ptr(struct symbol
*sym
)
272 if (sym
->type
!= SYM_NODE
)
274 sym
= get_base_type(sym
);
275 if (sym
->type
!= SYM_PTR
)
277 sym
= get_base_type(sym
);
281 static struct symbol
*get_struct_sym(struct expression
*expr
)
283 struct symbol
*base_type
;
284 struct symbol
*parent_struct
;
287 if (expr
->type
!= EXPR_PREOP
)
291 if (expr
->type
== EXPR_DEREF
) {
292 parent_struct
= get_struct_sym(expr
->deref
);
296 FOR_EACH_PTR(parent_struct
->symbol_list
, tmp
) {
297 if (tmp
->ident
== expr
->member
)
299 } END_FOR_EACH_PTR(tmp
);
300 if (!tmp
|| tmp
->ident
!= expr
->member
)
302 base_type
= get_base_type(tmp
);
303 } else if (expr
->type
== EXPR_SYMBOL
) {
304 base_type
= get_base_type(expr
->symbol
);
308 if (base_type
->type
!= SYM_PTR
)
310 base_type
= get_base_type(base_type
);
311 if (base_type
->type
!= SYM_STRUCT
&& base_type
->type
!= SYM_UNION
)
316 struct symbol
*get_deref_type(struct expression
*expr
)
318 struct ident
*member
= expr
->member
;
319 struct symbol
*struct_sym
;
322 struct_sym
= get_struct_sym(expr
->deref
);
323 if (!struct_sym
|| (struct_sym
->type
!= SYM_STRUCT
324 && struct_sym
->type
!= SYM_UNION
))
326 FOR_EACH_PTR(struct_sym
->symbol_list
, tmp
) {
327 if (tmp
->ident
== member
)
328 return get_ptr_type_ptr(tmp
);
329 } END_FOR_EACH_PTR(tmp
);
333 struct symbol
*get_ptr_type(struct expression
*expr
)
335 struct symbol
*ptr_type
= NULL
;
339 if (expr
->type
== EXPR_DEREF
)
340 ptr_type
= get_deref_type(expr
);
341 if (expr
->type
== EXPR_SYMBOL
)
342 ptr_type
= get_ptr_type_ptr(expr
->symbol
);
346 int sym_name_is(const char *name
, struct expression
*expr
)
350 if (expr
->type
!= EXPR_SYMBOL
)
352 if (!strcmp(expr
->symbol_name
->name
, name
))
357 static int _get_value(struct expression
*expr
, int *discard
)
369 expr
= strip_expr(expr
);
376 if (!strcmp("-", show_special(expr
->op
)))
377 ret
= - _get_value(expr
->unop
, discard
);
384 if (!show_special(expr
->op
)) {
388 left
= _get_value(expr
->left
, discard
);
389 right
= _get_value(expr
->right
, discard
);
390 if (!strcmp("*", show_special(expr
->op
))) {
392 } else if (!strcmp("/", show_special(expr
->op
))) {
394 } else if (!strcmp("+", show_special(expr
->op
))) {
396 } else if (!strcmp("-", show_special(expr
->op
))) {
398 } else if (!strcmp("|", show_special(expr
->op
))) {
400 } else if (!strcmp("&", show_special(expr
->op
))) {
402 } else if (!strcmp(">>", show_special(expr
->op
))) {
404 } else if (!strcmp("<<", show_special(expr
->op
))) {
412 if (expr
->cast_type
&& get_base_type(expr
->cast_type
))
413 ret
= (get_base_type(expr
->cast_type
))->bit_size
/ 8;
418 //printf("ouchies-->%d\n", expr->type);
426 /* returns UNDEFINED on error */
427 int get_value(struct expression
*expr
)
429 return _get_value(expr
, NULL
);
432 int is_zero(struct expression
*expr
)
434 if (get_value(expr
) == 0)
439 const char *show_state(struct smatch_state
*state
)
446 struct statement
*get_block_thing(struct expression
*expr
)
448 /* What are those things called? if (({....; ret;})) { ...*/
450 if (expr
->type
!= EXPR_PREOP
)
454 if (expr
->unop
->type
!= EXPR_STATEMENT
)
456 if (expr
->unop
->statement
->type
!= STMT_COMPOUND
)
458 return expr
->unop
->statement
;
461 struct expression
*strip_expr(struct expression
*expr
)
468 return strip_expr(expr
->cast_expression
);
470 if (expr
->op
== '(' && expr
->unop
->type
== EXPR_STATEMENT
&&
471 expr
->unop
->statement
->type
== STMT_COMPOUND
)
474 return strip_expr(expr
->unop
);