Fix usage message.
[smatch.git] / smatch_helper.c
blob29d94627b0ab03fa12e4e52bc63cbf2a17a7326b
1 /*
2 * sparse/smatch_helper.c
4 * Copyright (C) 2006 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
8 */
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include "allocate.h"
13 #include "smatch.h"
15 static int star_count;
16 #define VAR_LEN 512
19 char *alloc_string(char *str)
21 char *tmp;
23 if (!str)
24 return NULL;
25 tmp = malloc(strlen(str) + 1);
26 strcpy(tmp, str);
27 return tmp;
30 void free_string(char *str)
32 free(str);
35 static void prepend(char *dest, const char *data, int buff_len)
37 int space_needed;
38 int i;
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++)
44 dest[i] = data[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,
54 int num)
56 struct expression *expr;
57 int i = 0;
59 if (!args)
60 return NULL;
62 FOR_EACH_PTR(args, expr) {
63 if (i == num)
64 return expr;
65 i++;
66 } END_FOR_EACH_PTR(expr);
67 return NULL;
70 static void __get_variable_from_expr(struct symbol **sym_ptr, char *buf,
71 struct expression *expr, int len,
72 int *complicated)
74 switch(expr->type) {
75 case EXPR_DEREF:
76 prepend(buf, expr->member->name, len);
77 if (!strcmp(show_special(expr->deref->op), "*"))
78 prepend(buf, "->", len);
79 else
80 prepend(buf, ".", len);
82 //printf("debug: %d\n", expr->deref
84 __get_variable_from_expr(sym_ptr, buf, expr->deref,
85 len, complicated);
86 return;
87 case EXPR_SYMBOL:
88 if (expr->symbol_name)
89 prepend(buf, expr->symbol_name->name, len);
90 if (sym_ptr) {
91 if (*sym_ptr)
92 *complicated = 1;
93 *sym_ptr = expr->symbol;
95 return;
96 case EXPR_PREOP: {
97 const char *tmp;
99 if (expr->op == '*')
100 star_count++;
102 __get_variable_from_expr(sym_ptr, buf, expr->unop,
103 len, complicated);
104 tmp = show_special(expr->op);
105 if (tmp[0] == '*') {
106 if (star_count-- >= 0) {
107 prepend(buf, tmp, len);
109 } else {
110 prepend(buf, tmp, len);
113 if (tmp[0] == '(') {
114 strncat(buf, ")", len);
115 buf[len - 1] = '\0';
118 if ((!strcmp(tmp, "--")) || (!strcmp(tmp, "++")))
119 *complicated = 1;
121 return;
123 case EXPR_POSTOP: {
124 const char *tmp;
126 tmp = show_special(expr->op);
127 prepend(buf, tmp, len);
128 __get_variable_from_expr(sym_ptr, buf, expr->unop,
129 len, complicated);
131 if ((!strcmp(tmp, "--")) || (!strcmp(tmp, "++")))
132 *complicated = 1;
134 return;
136 case EXPR_BINOP: {
137 const char *tmp;
139 *complicated = 1;
140 prepend(buf, ")", len);
141 __get_variable_from_expr(NULL, buf, expr->right, len,
142 complicated);
143 tmp = show_special(expr->op);
144 prepend(buf, tmp, len);
145 __get_variable_from_expr(sym_ptr, buf, expr->left,
146 len, complicated);
147 prepend(buf, "(", len);
148 return;
150 case EXPR_VALUE: {
151 char tmp[25];
153 snprintf(tmp, 25, "%lld", expr->value);
154 prepend(buf, tmp, len);
155 return;
157 case EXPR_STRING:
158 prepend(buf, expr->string->data, len);
159 return;
160 case EXPR_CALL: {
161 struct expression *tmp;
162 int i = 0;
164 *complicated = 1;
165 prepend(buf, ")", len);
166 FOR_EACH_PTR_REVERSE(expr->args, tmp) {
167 if (i++)
168 prepend(buf, ", ", len);
169 __get_variable_from_expr(NULL, buf, tmp, len,
170 complicated);
171 } END_FOR_EACH_PTR_REVERSE(tmp);
172 prepend(buf, "(", len);
173 __get_variable_from_expr(NULL, buf, expr->fn, len,
174 complicated);
175 return;
177 case EXPR_CAST:
178 __get_variable_from_expr(sym_ptr, buf,
179 expr->cast_expression, len,
180 complicated);
181 return;
182 case EXPR_SIZEOF: {
183 int size;
184 char tmp[25];
186 if (expr->cast_type && get_base_type(expr->cast_type)) {
187 size = (get_base_type(expr->cast_type))->bit_size;
188 snprintf(tmp, 25, "%d", size);
189 prepend(buf, tmp, len);
191 return;
193 default:
194 *complicated = 1;
195 //printf("unknown type = %d\n", expr->type);
196 return;
202 * This is returns a stylized "c looking" representation of the
203 * variable name.
205 * It uses the same buffer every time so you have to save the result
206 * yourself if you want to keep it.
210 char *get_variable_from_expr_complex(struct expression *expr, struct symbol **sym_ptr)
212 static char var_name[VAR_LEN];
213 int junk;
215 if (sym_ptr)
216 *sym_ptr = NULL;
217 star_count = 0;
218 var_name[0] = '\0';
220 if (!expr)
221 return NULL;
222 __get_variable_from_expr(sym_ptr, var_name, expr, sizeof(var_name),
223 &junk);
225 return var_name;
229 * get_variable_from_expr_simple() only returns simple variables.
230 * If it's a complicated variable like a->foo instead of just 'a'
231 * then it returns NULL.
234 char *get_variable_from_expr(struct expression *expr,
235 struct symbol **sym_ptr)
237 static char var_name[VAR_LEN];
238 int complicated = 0;
240 if (sym_ptr)
241 *sym_ptr = NULL;
242 star_count = 0;
243 var_name[0] = '\0';
245 if (!expr)
246 return NULL;
247 expr = strip_expr(expr);
248 __get_variable_from_expr(sym_ptr, var_name, expr, sizeof(var_name),
249 &complicated);
251 if (complicated) {
252 if (sym_ptr)
253 *sym_ptr = NULL;
254 return NULL;
256 return alloc_string(var_name);
259 int sym_name_is(const char *name, struct expression *expr)
261 if (!expr)
262 return 0;
263 if (expr->type != EXPR_SYMBOL)
264 return 0;
265 if (!strcmp(expr->symbol_name->name, name))
266 return 1;
267 return 0;
270 static int _get_value(struct expression *expr, int *discard)
272 int dis = 0;
273 int ret = UNDEFINED;
275 if (!expr)
276 return UNDEFINED;
277 if (!discard)
278 discard = &dis;
279 if (*discard)
280 return UNDEFINED;
282 switch (expr->type){
283 case EXPR_VALUE:
284 ret = expr->value;
285 break;
286 case EXPR_PREOP:
287 if (!strcmp("-", show_special(expr->op)))
288 ret = - _get_value(expr->unop, discard);
289 break;
290 case EXPR_BINOP:
291 if (show_special(expr->op) &&
292 !strcmp("*", show_special(expr->op)))
293 ret = _get_value(expr->left, discard)
294 * _get_value(expr->right, discard);
295 break;
296 case EXPR_SIZEOF:
297 if (expr->cast_type && get_base_type(expr->cast_type))
298 ret = (get_base_type(expr->cast_type))->bit_size / 8;
299 if (expr->cast_expression)
300 ;//printf("debugs %d\n", expr->cast_expression->type);
301 break;
302 default:
303 //printf("ouchies-->%d\n", expr->type);
304 *discard = 1;
306 if (*discard)
307 return UNDEFINED;
308 return ret;
311 int get_value(struct expression *expr)
313 return _get_value(expr, NULL);
316 int is_zero(struct expression *expr)
318 if (expr->type == EXPR_VALUE && expr->value == 0)
319 return 1;
320 if (expr->op == '(')
321 return is_zero(expr->unop);
322 if (expr->type == EXPR_CAST)
323 return is_zero(expr->cast_expression);
324 return 0;
327 const char *show_state(struct smatch_state *state)
329 if (!state)
330 return NULL;
331 return state->name;
334 struct expression *strip_expr(struct expression *expr)
337 switch(expr->type) {
338 case EXPR_CAST:
339 return strip_expr(expr->cast_expression);
340 case EXPR_PREOP:
341 if (expr->op == '(')
342 return strip_expr(expr->unop);
344 return expr;