validation: delete obsolete dev_hold() check
[smatch.git] / smatch_helper.c
blob64e40925aad783c19f6f78be1f3139a975bd6b7e
1 /*
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.
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include "allocate.h"
25 #include "smatch.h"
26 #include "smatch_extra.h"
27 #include "smatch_slist.h"
29 #define VAR_LEN 512
31 char *alloc_string(const char *str)
33 char *tmp;
35 if (!str)
36 return NULL;
37 tmp = malloc(strlen(str) + 1);
38 strcpy(tmp, str);
39 return tmp;
42 char *alloc_string_newline(const char *str)
44 char *tmp;
45 int len;
47 if (!str)
48 return NULL;
49 len = strlen(str);
50 tmp = malloc(len + 2);
51 snprintf(tmp, len + 2, "%s\n", str);
52 return tmp;
55 void free_string(char *str)
57 free(str);
60 void remove_parens(char *str)
62 char *src, *dst;
64 dst = src = str;
65 while (*src != '\0') {
66 if (*src == '(' || *src == ')') {
67 src++;
68 continue;
70 *dst++ = *src++;
72 *dst = *src;
75 struct smatch_state *alloc_state_num(int num)
77 struct smatch_state *state;
78 static char buff[256];
80 state = __alloc_smatch_state(0);
81 snprintf(buff, 255, "%d", num);
82 buff[255] = '\0';
83 state->name = alloc_string(buff);
84 state->data = INT_PTR(num);
85 return state;
88 struct smatch_state *alloc_state_str(const char *name)
90 struct smatch_state *state;
92 state = __alloc_smatch_state(0);
93 state->name = alloc_string(name);
94 return state;
97 struct smatch_state *merge_str_state(struct smatch_state *s1, struct smatch_state *s2)
99 if (!s1->name || !s2->name)
100 return &merged;
101 if (strcmp(s1->name, s2->name) == 0)
102 return s1;
103 return &merged;
106 struct smatch_state *alloc_state_expr(struct expression *expr)
108 struct smatch_state *state;
109 char *name;
111 expr = strip_expr(expr);
112 name = expr_to_str(expr);
113 if (!name)
114 return NULL;
116 state = __alloc_smatch_state(0);
117 state->name = alloc_sname(name);
118 free_string(name);
119 state->data = expr;
120 return state;
123 static int FORMAT_ATTR(4) append(char *dest, int off, int len, const char *fmt, ...)
125 int n;
126 va_list args;
128 if (len <= 0 || off < 0 || off >= len - 1)
129 return 0;
131 va_start(args, fmt);
132 n = vsnprintf(dest + off, len - off, fmt, args);
133 va_end(args);
135 if (n > len - off - 1)
136 return len - off - 1;
137 return n;
141 * If you have "foo(a, b, 1);" then use
142 * get_argument_from_call_expr(expr, 0) to return the expression for
143 * a. Yes, it does start counting from 0.
145 struct expression *get_argument_from_call_expr(struct expression_list *args,
146 int num)
148 struct expression *expr;
149 int i = 0;
151 if (!args)
152 return NULL;
154 FOR_EACH_PTR(args, expr) {
155 if (i == num)
156 return expr;
157 i++;
158 } END_FOR_EACH_PTR(expr);
159 return NULL;
162 struct expression *get_array_expr(struct expression *expr)
164 struct expression *parent;
165 struct symbol *type;
167 if (expr->type != EXPR_BINOP || expr->op != '+')
168 return NULL;
170 type = get_type(expr->left);
171 if (!type)
172 return NULL;
173 if (type->type == SYM_ARRAY)
174 return expr->left;
175 if (type->type != SYM_PTR)
176 return NULL;
178 parent = expr_get_parent_expr(expr);
179 if (!parent) /* Sometimes we haven't set up the ->parent yet. FIXME!! */
180 return expr->left;
181 if (parent->type == EXPR_PREOP && parent->op == '*')
182 return expr->left;
184 return NULL;
187 static struct expression *strip_star_address(struct expression *expr)
189 struct expression *unop;
191 if (expr->type != EXPR_PREOP || expr->op != '*')
192 return expr;
193 unop = strip_parens(expr->unop);
194 if (unop->type != EXPR_PREOP || unop->op != '&')
195 return expr;
197 return unop->unop;
200 static struct expression *strip_parens_symbol(struct expression *expr)
202 struct expression *unop;
204 if (expr->type != EXPR_PREOP || expr->op != '(')
205 return expr;
206 unop = strip_parens(expr->unop);
207 if (unop->type != EXPR_SYMBOL)
208 return expr;
209 return unop;
212 static int __get_variable_from_expr(struct symbol **sym_ptr, char *buf,
213 struct expression *expr, int off, int len,
214 int *complicated)
216 int orig_off = off;
218 if (!expr) {
219 /* can't happen on valid code */
220 *complicated = 1;
221 return 0;
224 expr = strip_star_address(expr);
225 expr = strip_parens_symbol(expr);
227 switch (expr->type) {
228 case EXPR_DEREF: {
229 struct expression *deref;
230 int op;
232 op = expr->op;
233 deref = expr->deref;
235 /* this is pure guess work and nonsense programming */
236 if (deref->type == EXPR_PREOP && deref->op == '*') {
237 op = '*';
238 deref = deref->unop;
241 off += __get_variable_from_expr(sym_ptr, buf, deref, off, len, complicated);
243 if (op == '*')
244 off += append(buf, off, len, "->");
245 else
246 off += append(buf, off, len, ".");
248 if (expr->member)
249 off += append(buf, off, len, "%s", expr->member->name);
250 else
251 off += append(buf, off, len, "unknown_member");
252 return off - orig_off;
254 case EXPR_SYMBOL:
255 if (expr->symbol_name)
256 off += append(buf, off, len, "%s", expr->symbol_name->name);
257 if (sym_ptr) {
258 if (*sym_ptr)
259 *complicated = 1;
260 *sym_ptr = expr->symbol;
262 return off - orig_off;
263 case EXPR_PREOP: {
264 const char *tmp;
266 if (get_expression_statement(expr)) {
267 *complicated = 2;
268 return 0;
270 if (expr->op == SPECIAL_DECREMENT ||
271 expr->op == SPECIAL_INCREMENT)
272 *complicated = 1;
274 if (expr->op == '*' && get_array_expr(expr->unop))
275 tmp = "";
276 else
277 tmp = show_special(expr->op);
279 off += append(buf, off, len, "%s", tmp);
280 off += __get_variable_from_expr(sym_ptr, buf, expr->unop, off,
281 len, complicated);
282 if (expr->op == '(')
283 off += append(buf, off, len, ")");
285 return off - orig_off;
287 case EXPR_POSTOP: {
288 off += __get_variable_from_expr(sym_ptr, buf, expr->unop, off, len,
289 complicated);
290 off += append(buf, off, len, "%s", show_special(expr->op));
292 if (expr->op == SPECIAL_DECREMENT || expr->op == SPECIAL_INCREMENT)
293 *complicated = 1;
294 return off - orig_off;
296 case EXPR_ASSIGNMENT:
297 case EXPR_COMPARE:
298 case EXPR_LOGICAL:
299 case EXPR_BINOP: {
300 struct expression *array_expr;
302 *complicated = 1;
303 array_expr = get_array_expr(expr);
304 if (array_expr) {
305 off += __get_variable_from_expr(sym_ptr, buf, array_expr, off, len, complicated);
306 off += append(buf, off, len, "[");
307 } else {
308 off += __get_variable_from_expr(sym_ptr, buf, expr->left, off, len, complicated);
309 off += append(buf, off, len, " %s ", show_special(expr->op));
311 off += __get_variable_from_expr(NULL, buf, expr->right, off, len, complicated);
312 if (array_expr)
313 off += append(buf, off, len, "]");
314 return off - orig_off;
316 case EXPR_VALUE: {
317 sval_t sval = {};
319 *complicated = 1;
320 if (!get_value(expr, &sval))
321 return 0;
322 off += append(buf, off, len, "%s", sval_to_numstr(sval));
323 return off - orig_off;
325 case EXPR_FVALUE: {
326 sval_t sval = {};
328 *complicated = 1;
329 if (!get_value(expr, &sval))
330 return 0;
332 off += append(buf, off, len, "%s", sval_to_numstr(sval));
333 return off - orig_off;
335 case EXPR_STRING:
336 off += append(buf, off, len, "\"");
337 if (expr->string)
338 off += append(buf, off, len, "%s", expr->string->data);
339 off += append(buf, off, len, "\"");
340 return off - orig_off;
341 case EXPR_CALL: {
342 struct expression *tmp;
343 int i;
345 *complicated = 1;
346 off += __get_variable_from_expr(NULL, buf, expr->fn, off, len, complicated);
347 off += append(buf, off, len, "(");
348 i = 0;
349 FOR_EACH_PTR(expr->args, tmp) {
350 if (i++)
351 off += append(buf, off, len, ", ");
352 off += __get_variable_from_expr(NULL, buf, tmp, off, len, complicated);
353 } END_FOR_EACH_PTR(tmp);
354 off += append(buf, off, len, ")");
355 return off - orig_off;
357 case EXPR_CAST:
358 case EXPR_FORCE_CAST:
359 return __get_variable_from_expr(sym_ptr, buf,
360 expr->cast_expression, off, len,
361 complicated);
362 case EXPR_SIZEOF: {
363 sval_t sval;
364 int size;
366 if (expr->cast_type && get_base_type(expr->cast_type)) {
367 size = type_bytes(get_base_type(expr->cast_type));
368 off += append(buf, off, len, "%d", size);
369 } else if (get_value(expr, &sval)) {
370 off += append(buf, off, len, "%s", sval_to_str(sval));
372 return off - orig_off;
374 case EXPR_IDENTIFIER:
375 *complicated = 1;
376 if (expr->expr_ident)
377 off += append(buf, off, len, "%s", expr->expr_ident->name);
378 return off - orig_off;
379 case EXPR_SELECT:
380 case EXPR_CONDITIONAL:
381 *complicated = 1;
382 off += append(buf, off, len, "(");
383 off += __get_variable_from_expr(NULL, buf, expr->conditional, off, len, complicated);
384 off += append(buf, off, len, ") ?");
385 if (expr->cond_true)
386 off += __get_variable_from_expr(NULL, buf, expr->cond_true, off, len, complicated);
387 off += append(buf, off, len, ":");
388 off += __get_variable_from_expr(NULL, buf, expr->cond_false, off, len, complicated);
389 return off - orig_off;
390 default:
391 off += append(buf, off, len, "$expr_%p(%d)", expr, expr->type);
392 return off - orig_off;
396 struct expr_str_cache_results {
397 struct expression *expr;
398 char str[VAR_LEN];
399 struct symbol *sym;
400 int complicated;
403 static void get_variable_from_expr(struct symbol **sym_ptr, char *buf,
404 struct expression *expr, int len,
405 int *complicated)
407 static struct expr_str_cache_results cached[8];
408 struct symbol *tmp_sym = NULL;
409 static int idx;
410 int i;
412 for (i = 0; i < ARRAY_SIZE(cached); i++) {
413 if (expr == cached[i].expr) {
414 strncpy(buf, cached[i].str, len);
415 if (sym_ptr)
416 *sym_ptr = cached[i].sym;
417 *complicated = cached[i].complicated;
418 return;
422 __get_variable_from_expr(&tmp_sym, buf, expr, 0, len, complicated);
423 if (sym_ptr)
424 *sym_ptr = tmp_sym;
426 if (expr->smatch_flags & Tmp)
427 return;
429 cached[idx].expr = expr;
430 strncpy(cached[idx].str, buf, VAR_LEN);
431 cached[idx].sym = tmp_sym;
432 cached[idx].complicated = *complicated;
434 idx = (idx + 1) % ARRAY_SIZE(cached);
438 * This is returns a stylized "c looking" representation of the
439 * variable name.
441 * It uses the same buffer every time so you have to save the result
442 * yourself if you want to keep it.
446 char *expr_to_str_sym(struct expression *expr, struct symbol **sym_ptr)
448 static char var_name[VAR_LEN];
449 int complicated = 0;
451 if (sym_ptr)
452 *sym_ptr = NULL;
453 var_name[0] = '\0';
455 if (!expr)
456 return NULL;
457 get_variable_from_expr(sym_ptr, var_name, expr, sizeof(var_name),
458 &complicated);
459 if (complicated < 2)
460 return alloc_string(var_name);
461 else
462 return NULL;
465 char *expr_to_str(struct expression *expr)
467 return expr_to_str_sym(expr, NULL);
471 * get_variable_from_expr_simple() only returns simple variables.
472 * If it's a complicated variable like a->foo[x] instead of just 'a->foo'
473 * then it returns NULL.
475 char *expr_to_var_sym(struct expression *expr,
476 struct symbol **sym_ptr)
478 static char var_name[VAR_LEN];
479 int complicated = 0;
481 if (sym_ptr)
482 *sym_ptr = NULL;
483 var_name[0] = '\0';
485 if (!expr)
486 return NULL;
487 expr = strip_expr(expr);
488 get_variable_from_expr(sym_ptr, var_name, expr, sizeof(var_name),
489 &complicated);
491 if (complicated) {
492 if (sym_ptr)
493 *sym_ptr = NULL;
494 return NULL;
496 return alloc_string(var_name);
499 char *expr_to_var(struct expression *expr)
501 return expr_to_var_sym(expr, NULL);
504 struct symbol *expr_to_sym(struct expression *expr)
506 struct symbol *sym;
507 char *name;
509 name = expr_to_var_sym(expr, &sym);
510 free_string(name);
511 return sym;
514 int get_complication_score(struct expression *expr)
516 expr = strip_expr(expr);
519 * Don't forget to keep get_complication_score() and store_all_links()
520 * in sync.
524 if (!expr)
525 return 990;
527 switch (expr->type) {
528 case EXPR_CALL:
529 return 991;
530 case EXPR_COMPARE:
531 case EXPR_BINOP:
532 return get_complication_score(expr->left) +
533 get_complication_score(expr->right);
534 case EXPR_SYMBOL:
535 return 1;
536 case EXPR_PREOP:
537 if (expr->op == '*' || expr->op == '(')
538 return get_complication_score(expr->unop);
539 return 993;
540 case EXPR_DEREF:
541 return get_complication_score(expr->deref);
542 case EXPR_VALUE:
543 case EXPR_SIZEOF:
544 return 0;
545 default:
546 return 994;
550 struct expression *reorder_expr_alphabetically(struct expression *expr)
552 struct expression *ret;
553 char *left, *right;
555 if (expr->type != EXPR_BINOP)
556 return expr;
557 if (expr->op != '+' && expr->op != '*')
558 return expr;
560 left = expr_to_var(expr->left);
561 right = expr_to_var(expr->right);
562 ret = expr;
563 if (!left || !right)
564 goto free;
565 if (strcmp(left, right) <= 0)
566 goto free;
568 ret = binop_expression(expr->right, expr->op, expr->left);
569 free:
570 free_string(left);
571 free_string(right);
573 return ret;
576 char *expr_to_chunk_helper(struct expression *expr, struct symbol **sym, struct var_sym_list **vsl)
578 struct var_sym_list *tmp_vsl;
579 char *name;
580 struct symbol *tmp;
581 int score;
583 if (vsl)
584 *vsl = NULL;
585 if (sym)
586 *sym = NULL;
588 expr = strip_parens(expr);
589 if (!expr)
590 return NULL;
592 name = expr_to_var_sym(expr, &tmp);
593 if (name && tmp) {
594 if (sym)
595 *sym = tmp;
596 if (vsl)
597 add_var_sym(vsl, name, tmp);
598 return name;
600 free_string(name);
602 score = get_complication_score(expr);
603 if (score <= 0 || score > 2)
604 return NULL;
606 tmp_vsl = expr_to_vsl(expr);
607 if (vsl) {
608 *vsl = tmp_vsl;
609 if (!*vsl)
610 return NULL;
612 if (sym) {
613 if (ptr_list_size((struct ptr_list *)tmp_vsl) == 1) {
614 struct var_sym *vs;
616 vs = first_ptr_list((struct ptr_list *)tmp_vsl);
617 *sym = vs->sym;
621 expr = reorder_expr_alphabetically(expr);
623 return expr_to_str(expr);
626 char *expr_to_known_chunk_sym(struct expression *expr, struct symbol **sym)
628 return expr_to_chunk_helper(expr, sym, NULL);
631 char *expr_to_chunk_sym_vsl(struct expression *expr, struct symbol **sym, struct var_sym_list **vsl)
633 return expr_to_chunk_helper(expr, sym, vsl);
636 int sym_name_is(const char *name, struct expression *expr)
638 if (!expr)
639 return 0;
640 if (expr->type != EXPR_SYMBOL)
641 return 0;
642 if (!strcmp(expr->symbol_name->name, name))
643 return 1;
644 return 0;
647 int expr_is_zero(struct expression *expr)
649 sval_t sval;
651 if (get_value(expr, &sval) && sval.value == 0)
652 return 1;
653 return 0;
656 int is_array(struct expression *expr)
658 struct symbol *type;
660 expr = strip_expr(expr);
661 if (!expr)
662 return 0;
664 if (expr->type == EXPR_PREOP && expr->op == '*') {
665 expr = strip_expr(expr->unop);
666 if (!expr)
667 return 0;
668 if (expr->type == EXPR_BINOP && expr->op == '+')
669 return 1;
672 if (expr->type != EXPR_BINOP || expr->op != '+')
673 return 0;
675 type = get_type(expr->left);
676 if (!type || type->type != SYM_ARRAY)
677 return 0;
679 return 1;
682 struct expression *get_array_base(struct expression *expr)
684 if (!is_array(expr))
685 return NULL;
686 expr = strip_expr(expr);
687 if (expr->type == EXPR_PREOP && expr->op == '*')
688 expr = strip_expr(expr->unop);
689 if (expr->type != EXPR_BINOP || expr->op != '+')
690 return NULL;
691 return strip_parens(expr->left);
694 struct expression *get_array_offset(struct expression *expr)
696 if (!is_array(expr))
697 return NULL;
698 expr = strip_expr(expr);
699 if (expr->type == EXPR_PREOP && expr->op == '*')
700 expr = strip_expr(expr->unop);
701 if (expr->type != EXPR_BINOP || expr->op != '+')
702 return NULL;
703 return strip_parens(expr->right);
706 const char *show_state(struct smatch_state *state)
708 if (!state)
709 return NULL;
710 return state->name;
713 struct statement *get_expression_statement(struct expression *expr)
715 /* What are those things called? if (({....; ret;})) { ...*/
717 if (expr->type != EXPR_PREOP)
718 return NULL;
719 if (expr->op != '(')
720 return NULL;
721 if (!expr->unop)
722 return NULL;
723 if (expr->unop->type != EXPR_STATEMENT)
724 return NULL;
725 if (expr->unop->statement->type != STMT_COMPOUND)
726 return NULL;
727 return expr->unop->statement;
730 struct expression *strip_parens(struct expression *expr)
732 if (!expr)
733 return NULL;
735 if (expr->type == EXPR_PREOP) {
736 if (!expr->unop)
737 return expr; /* parsing invalid code */
739 if (expr->op == '(' && expr->unop->type == EXPR_STATEMENT &&
740 expr->unop->statement->type == STMT_COMPOUND)
741 return expr;
742 if (expr->op == '(')
743 return strip_parens(expr->unop);
745 return expr;
748 static struct expression *strip_expr_helper(struct expression *expr, bool set_parent)
750 if (!expr)
751 return NULL;
753 switch (expr->type) {
754 case EXPR_FORCE_CAST:
755 case EXPR_CAST:
756 if (set_parent)
757 expr_set_parent_expr(expr->cast_expression, expr);
759 if (!expr->cast_expression)
760 return expr;
761 return strip_expr_helper(expr->cast_expression, set_parent);
762 case EXPR_PREOP: {
763 struct expression *unop;
765 if (!expr->unop) /* parsing invalid code */
766 return expr;
767 if (set_parent)
768 expr_set_parent_expr(expr->unop, expr);
771 if (expr->op == '(' && expr->unop->type == EXPR_STATEMENT &&
772 expr->unop->statement->type == STMT_COMPOUND)
773 return expr;
775 unop = strip_expr_helper(expr->unop, set_parent);
777 if (expr->op == '*' && unop &&
778 unop->type == EXPR_PREOP && unop->op == '&') {
779 struct symbol *type = get_type(unop->unop);
781 if (type && type->type == SYM_ARRAY)
782 return expr;
783 return strip_expr_helper(unop->unop, set_parent);
786 if (expr->op == '(')
787 return unop;
789 return expr;
791 case EXPR_CONDITIONAL:
792 if (known_condition_true(expr->conditional)) {
793 if (expr->cond_true) {
794 if (set_parent)
795 expr_set_parent_expr(expr->cond_true, expr);
796 return strip_expr_helper(expr->cond_true, set_parent);
798 if (set_parent)
799 expr_set_parent_expr(expr->conditional, expr);
800 return strip_expr_helper(expr->conditional, set_parent);
802 if (known_condition_false(expr->conditional)) {
803 if (set_parent)
804 expr_set_parent_expr(expr->cond_false, expr);
805 return strip_expr_helper(expr->cond_false, set_parent);
807 return expr;
808 case EXPR_CALL:
809 if (sym_name_is("__builtin_expect", expr->fn) ||
810 sym_name_is("__builtin_bswap16", expr->fn) ||
811 sym_name_is("__builtin_bswap32", expr->fn) ||
812 sym_name_is("__builtin_bswap64", expr->fn)) {
813 expr = get_argument_from_call_expr(expr->args, 0);
814 return strip_expr_helper(expr, set_parent);
816 return expr;
818 return expr;
821 struct expression *strip_expr(struct expression *expr)
823 return strip_expr_helper(expr, false);
826 struct expression *strip_expr_set_parent(struct expression *expr)
828 return strip_expr_helper(expr, true);
831 static void delete_state_tracker(struct tracker *t)
833 __delete_state(t->owner, t->name, t->sym);
834 __free_tracker(t);
837 void scoped_state(int my_id, const char *name, struct symbol *sym)
839 struct tracker *t;
841 t = alloc_tracker(my_id, name, sym);
842 add_scope_hook((scope_hook *)&delete_state_tracker, t);
845 int is_error_return(struct expression *expr)
847 struct symbol *cur_func = cur_func_sym;
848 struct range_list *rl;
849 sval_t sval;
851 if (!expr)
852 return 0;
853 if (cur_func->type != SYM_NODE)
854 return 0;
855 cur_func = get_base_type(cur_func);
856 if (cur_func->type != SYM_FN)
857 return 0;
858 cur_func = get_base_type(cur_func);
859 if (cur_func == &void_ctype)
860 return 0;
861 if (option_project == PROJ_KERNEL &&
862 get_implied_rl(expr, &rl) &&
863 rl_type(rl) == &int_ctype &&
864 sval_is_negative(rl_min(rl)) &&
865 rl_max(rl).value == -1)
866 return 1;
867 if (!get_implied_value(expr, &sval))
868 return 0;
869 if (sval.value < 0)
870 return 1;
871 if (cur_func->type == SYM_PTR && sval.value == 0)
872 return 1;
873 return 0;
876 int getting_address(struct expression *expr)
878 int deref_count = 0;
880 while ((expr = expr_get_parent_expr(expr))) {
881 if (expr->type == EXPR_PREOP && expr->op == '*') {
882 /* &foo->bar->baz dereferences "foo->bar" */
883 if (deref_count == 0)
884 deref_count++;
885 return false;
887 if (expr->type == EXPR_PREOP && expr->op == '&')
888 return true;
890 return false;
893 int get_struct_and_member(struct expression *expr, const char **type, const char **member)
895 struct symbol *sym;
897 expr = strip_expr(expr);
898 if (expr->type != EXPR_DEREF)
899 return 0;
900 if (!expr->member)
901 return 0;
903 sym = get_type(expr->deref);
904 if (!sym)
905 return 0;
906 if (sym->type == SYM_UNION)
907 return 0;
908 if (!sym->ident)
909 return 0;
911 *type = sym->ident->name;
912 *member = expr->member->name;
913 return 1;
916 char *get_member_name(struct expression *expr)
918 char buf[256];
919 struct symbol *sym;
921 expr = strip_expr(expr);
922 if (!expr || expr->type != EXPR_DEREF)
923 return NULL;
924 if (!expr->member)
925 return NULL;
927 sym = get_type(expr->deref);
928 if (!sym)
929 return NULL;
930 if (sym->type == SYM_UNION) {
931 snprintf(buf, sizeof(buf), "(union %s)->%s",
932 sym->ident ? sym->ident->name : "anonymous",
933 expr->member->name);
934 return alloc_string(buf);
936 if (!sym->ident) {
937 struct expression *deref;
938 char *full, *outer;
939 int len;
942 * If we're in an anonymous struct then maybe we can find an
943 * outer struct name to use as a name. This code should be
944 * recursive and cleaner. I am not very proud of it.
948 deref = expr->deref;
949 if (deref->type != EXPR_DEREF || !deref->member)
950 return NULL;
951 sym = get_type(deref->deref);
952 if (!sym || sym->type != SYM_STRUCT || !sym->ident)
953 return NULL;
955 full = expr_to_str(expr);
956 if (!full)
957 return NULL;
958 deref = deref->deref;
959 if (deref->type == EXPR_PREOP && deref->op == '*')
960 deref = deref->unop;
961 outer = expr_to_str(deref);
962 if (!outer) {
963 free_string(full);
964 return NULL;
966 len = strlen(outer);
967 if (strncmp(outer, full, len) != 0) {
968 free_string(full);
969 free_string(outer);
970 return NULL;
972 if (full[len] == '-' && full[len + 1] == '>')
973 len += 2;
974 if (full[len] == '.')
975 len++;
976 snprintf(buf, sizeof(buf), "(struct %s)->%s", sym->ident->name, full + len);
977 free_string(outer);
978 free_string(full);
980 return alloc_string(buf);
982 snprintf(buf, sizeof(buf), "(struct %s)->%s", sym->ident->name, expr->member->name);
983 return alloc_string(buf);
986 int cmp_pos(struct position pos1, struct position pos2)
988 /* the stream position is ... */
989 if (pos1.stream > pos2.stream)
990 return -1;
991 if (pos1.stream < pos2.stream)
992 return 1;
994 if (pos1.line < pos2.line)
995 return -1;
996 if (pos1.line > pos2.line)
997 return 1;
999 if (pos1.pos < pos2.pos)
1000 return -1;
1001 if (pos1.pos > pos2.pos)
1002 return 1;
1004 return 0;
1007 int positions_eq(struct position pos1, struct position pos2)
1009 if (pos1.line != pos2.line)
1010 return 0;
1011 if (pos1.pos != pos2.pos)
1012 return 0;
1013 if (pos1.stream != pos2.stream)
1014 return 0;
1015 return 1;
1018 struct statement *get_current_statement(void)
1020 struct statement *prev, *tmp;
1022 prev = last_ptr_list((struct ptr_list *)big_statement_stack);
1024 if (!prev || !get_macro_name(prev->pos))
1025 return prev;
1027 FOR_EACH_PTR_REVERSE(big_statement_stack, tmp) {
1028 if (positions_eq(tmp->pos, prev->pos))
1029 continue;
1030 if (prev->pos.line > tmp->pos.line)
1031 return prev;
1032 return tmp;
1033 } END_FOR_EACH_PTR_REVERSE(tmp);
1034 return prev;
1037 struct statement *get_prev_statement(void)
1039 struct statement *tmp;
1040 int i;
1042 i = 0;
1043 FOR_EACH_PTR_REVERSE(big_statement_stack, tmp) {
1044 if (i++ == 1)
1045 return tmp;
1046 } END_FOR_EACH_PTR_REVERSE(tmp);
1047 return NULL;
1050 struct expression *get_last_expr_from_expression_stmt(struct expression *expr)
1052 struct statement *stmt;
1053 struct statement *last_stmt;
1055 while (expr->type == EXPR_PREOP && expr->op == '(')
1056 expr = expr->unop;
1057 if (expr->type != EXPR_STATEMENT)
1058 return NULL;
1059 stmt = expr->statement;
1060 if (!stmt)
1061 return NULL;
1062 if (stmt->type == STMT_COMPOUND) {
1063 last_stmt = last_ptr_list((struct ptr_list *)stmt->stmts);
1064 if (!last_stmt)
1065 return NULL;
1066 if (last_stmt->type == STMT_LABEL)
1067 last_stmt = last_stmt->label_statement;
1068 if (last_stmt->type != STMT_EXPRESSION)
1069 return NULL;
1070 return last_stmt->expression;
1072 if (stmt->type == STMT_EXPRESSION)
1073 return stmt->expression;
1074 return NULL;
1077 int ms_since(struct timeval *start)
1079 struct timeval end;
1080 double diff;
1082 gettimeofday(&end, NULL);
1083 diff = (end.tv_sec - start->tv_sec) * 1000.0;
1084 diff += (end.tv_usec - start->tv_usec) / 1000.0;
1085 return (int)diff;
1088 int parent_is_gone_var_sym(const char *name, struct symbol *sym)
1090 if (!name || !sym)
1091 return 0;
1093 if (parent_is_err_or_null_var_sym(name, sym) ||
1094 parent_is_free_var_sym(name, sym))
1095 return 1;
1096 return 0;
1099 int parent_is_gone(struct expression *expr)
1101 struct symbol *sym;
1102 char *var;
1103 int ret = 0;
1105 expr = strip_expr(expr);
1106 var = expr_to_var_sym(expr, &sym);
1107 if (!var || !sym)
1108 goto free;
1109 ret = parent_is_gone_var_sym(var, sym);
1110 free:
1111 free_string(var);
1112 return ret;
1115 int invert_op(int op)
1117 switch (op) {
1118 case '*':
1119 return '/';
1120 case '/':
1121 return '*';
1122 case '+':
1123 return '-';
1124 case '-':
1125 return '+';
1126 case SPECIAL_LEFTSHIFT:
1127 return SPECIAL_RIGHTSHIFT;
1128 case SPECIAL_RIGHTSHIFT:
1129 return SPECIAL_LEFTSHIFT;
1131 return 0;
1134 int op_remove_assign(int op)
1136 switch (op) {
1137 case SPECIAL_ADD_ASSIGN:
1138 return '+';
1139 case SPECIAL_SUB_ASSIGN:
1140 return '-';
1141 case SPECIAL_MUL_ASSIGN:
1142 return '*';
1143 case SPECIAL_DIV_ASSIGN:
1144 return '/';
1145 case SPECIAL_MOD_ASSIGN:
1146 return '%';
1147 case SPECIAL_AND_ASSIGN:
1148 return '&';
1149 case SPECIAL_OR_ASSIGN:
1150 return '|';
1151 case SPECIAL_XOR_ASSIGN:
1152 return '^';
1153 case SPECIAL_SHL_ASSIGN:
1154 return SPECIAL_LEFTSHIFT;
1155 case SPECIAL_SHR_ASSIGN:
1156 return SPECIAL_RIGHTSHIFT;
1157 default:
1158 return op;
1162 int expr_equiv(struct expression *one, struct expression *two)
1164 struct symbol *one_sym = NULL;
1165 struct symbol *two_sym = NULL;
1166 char *one_name = NULL;
1167 char *two_name = NULL;
1168 int ret = 0;
1170 if (!one || !two)
1171 return 0;
1172 if (one->type != two->type)
1173 return 0;
1174 if (is_fake_call(one) || is_fake_call(two))
1175 return 0;
1177 one_name = expr_to_str_sym(one, &one_sym);
1178 if (!one_name)
1179 goto free;
1180 two_name = expr_to_str_sym(two, &two_sym);
1181 if (!two_name)
1182 goto free;
1183 if (one_sym != two_sym)
1184 goto free;
1186 * This is a terrible hack because expr_to_str() sometimes gives up in
1187 * the middle and just returns what it has. If you see a () you know
1188 * the string is bogus.
1190 if (strstr(one_name, "()"))
1191 goto free;
1192 if (strcmp(one_name, two_name) == 0)
1193 ret = 1;
1194 free:
1195 free_string(one_name);
1196 free_string(two_name);
1197 return ret;
1200 void push_int(struct int_stack **stack, int num)
1202 int *munged;
1205 * Just put the int on directly instead of a pointer to the int.
1206 * Shift it to the left because Sparse uses the last two bits.
1207 * This is sort of a dirty hack, yes.
1210 munged = INT_PTR(num << 2);
1212 add_ptr_list(stack, munged);
1215 int pop_int(struct int_stack **stack)
1217 int *num;
1219 num = last_ptr_list((struct ptr_list *)*stack);
1220 delete_ptr_list_last((struct ptr_list **)stack);
1222 return PTR_INT(num) >> 2;