24
25 ALLOCATOR(smatch_state, "smatch state");
26 ALLOCATOR(sm_state, "sm state");
27 ALLOCATOR(named_stree, "named slist");
28 __DO_ALLOCATOR(char, 1, 4, "state names", sname);
29
30 int sm_state_counter;
31
32 static struct stree_stack *all_pools;
33
34 const char *show_sm(struct sm_state *sm)
35 {
36 static char buf[256];
37 struct sm_state *tmp;
38 int pos;
39 int i;
40
41 if (!sm)
42 return "<none>";
43
44 pos = snprintf(buf, sizeof(buf), "[%s] '%s' = '%s'",
45 check_name(sm->owner), sm->name, show_state(sm->state));
46 if (pos > sizeof(buf))
47 goto truncate;
48
49 if (ptr_list_size((struct ptr_list *)sm->possible) == 1)
50 return buf;
51
52 pos += snprintf(buf + pos, sizeof(buf) - pos, " (");
53 if (pos > sizeof(buf))
54 goto truncate;
55 i = 0;
56 FOR_EACH_PTR(sm->possible, tmp) {
57 if (i++)
58 pos += snprintf(buf + pos, sizeof(buf) - pos, ", ");
59 if (pos > sizeof(buf))
60 goto truncate;
61 pos += snprintf(buf + pos, sizeof(buf) - pos, "%s",
62 show_state(tmp->state));
63 if (pos > sizeof(buf))
64 goto truncate;
65 } END_FOR_EACH_PTR(tmp);
674 int owner, const char *name,
675 struct symbol *sym)
676 {
677 struct sm_state *sm;
678
679 sm = get_sm_state_stree_stack(stack, owner, name, sym);
680 if (sm)
681 return sm->state;
682 return NULL;
683 }
684
685 static void match_states_stree(struct stree **one, struct stree **two)
686 {
687 struct smatch_state *tmp_state;
688 struct sm_state *sm;
689 struct state_list *add_to_one = NULL;
690 struct state_list *add_to_two = NULL;
691 AvlIter one_iter;
692 AvlIter two_iter;
693
694 avl_iter_begin(&one_iter, *one, FORWARD);
695 avl_iter_begin(&two_iter, *two, FORWARD);
696
697 for (;;) {
698 if (!one_iter.sm && !two_iter.sm)
699 break;
700 if (cmp_tracker(one_iter.sm, two_iter.sm) < 0) {
701 __set_fake_cur_stree_fast(*two);
702 tmp_state = __client_unmatched_state_function(one_iter.sm);
703 __pop_fake_cur_stree_fast();
704 sm = alloc_state_no_name(one_iter.sm->owner, one_iter.sm->name,
705 one_iter.sm->sym, tmp_state);
706 add_ptr_list(&add_to_two, sm);
707 avl_iter_next(&one_iter);
708 } else if (cmp_tracker(one_iter.sm, two_iter.sm) == 0) {
709 avl_iter_next(&one_iter);
710 avl_iter_next(&two_iter);
711 } else {
712 __set_fake_cur_stree_fast(*one);
713 tmp_state = __client_unmatched_state_function(two_iter.sm);
714 __pop_fake_cur_stree_fast();
715 sm = alloc_state_no_name(two_iter.sm->owner, two_iter.sm->name,
716 two_iter.sm->sym, tmp_state);
717 add_ptr_list(&add_to_one, sm);
718 avl_iter_next(&two_iter);
719 }
720 }
721
722 FOR_EACH_PTR(add_to_one, sm) {
723 avl_insert(one, sm);
724 } END_FOR_EACH_PTR(sm);
725
726 FOR_EACH_PTR(add_to_two, sm) {
727 avl_insert(two, sm);
728 } END_FOR_EACH_PTR(sm);
729
730 free_slist(&add_to_one);
731 free_slist(&add_to_two);
732 }
733
734 static void call_pre_merge_hooks(struct stree **one, struct stree **two)
735 {
736 struct sm_state *sm, *other;
737
738 save_all_states();
739
740 __swap_cur_stree(*one);
741 FOR_EACH_SM(*two, sm) {
742 other = get_sm_state(sm->owner, sm->name, sm->sym);
743 if (other == sm)
744 continue;
745 call_pre_merge_hook(sm);
746 } END_FOR_EACH_SM(sm);
747 *one = clone_stree(__get_cur_stree());
748
749 __swap_cur_stree(*two);
750 FOR_EACH_SM(*one, sm) {
751 other = get_sm_state(sm->owner, sm->name, sm->sym);
752 if (other == sm)
753 continue;
754 call_pre_merge_hook(sm);
755 } END_FOR_EACH_SM(sm);
756 *two = clone_stree(__get_cur_stree());
757
758 restore_all_states();
759 }
760
761 static void clone_pool_havers_stree(struct stree **stree)
762 {
763 struct sm_state *sm, *tmp;
764 struct state_list *slist = NULL;
765
766 FOR_EACH_SM(*stree, sm) {
767 if (sm->pool) {
768 tmp = clone_sm(sm);
769 add_ptr_list(&slist, tmp);
770 }
771 } END_FOR_EACH_SM(sm);
772
773 FOR_EACH_PTR(slist, sm) {
774 avl_insert(stree, sm);
775 } END_FOR_EACH_PTR(sm);
776
777 free_slist(&slist);
778 }
|
24
25 ALLOCATOR(smatch_state, "smatch state");
26 ALLOCATOR(sm_state, "sm state");
27 ALLOCATOR(named_stree, "named slist");
28 __DO_ALLOCATOR(char, 1, 4, "state names", sname);
29
30 int sm_state_counter;
31
32 static struct stree_stack *all_pools;
33
34 const char *show_sm(struct sm_state *sm)
35 {
36 static char buf[256];
37 struct sm_state *tmp;
38 int pos;
39 int i;
40
41 if (!sm)
42 return "<none>";
43
44 pos = snprintf(buf, sizeof(buf), "[%s] %s = '%s'%s",
45 check_name(sm->owner), sm->name, show_state(sm->state),
46 sm->merged ? " [merged]" : "");
47 if (pos > sizeof(buf))
48 goto truncate;
49
50 if (ptr_list_size((struct ptr_list *)sm->possible) == 1)
51 return buf;
52
53 pos += snprintf(buf + pos, sizeof(buf) - pos, " (");
54 if (pos > sizeof(buf))
55 goto truncate;
56 i = 0;
57 FOR_EACH_PTR(sm->possible, tmp) {
58 if (i++)
59 pos += snprintf(buf + pos, sizeof(buf) - pos, ", ");
60 if (pos > sizeof(buf))
61 goto truncate;
62 pos += snprintf(buf + pos, sizeof(buf) - pos, "%s",
63 show_state(tmp->state));
64 if (pos > sizeof(buf))
65 goto truncate;
66 } END_FOR_EACH_PTR(tmp);
675 int owner, const char *name,
676 struct symbol *sym)
677 {
678 struct sm_state *sm;
679
680 sm = get_sm_state_stree_stack(stack, owner, name, sym);
681 if (sm)
682 return sm->state;
683 return NULL;
684 }
685
686 static void match_states_stree(struct stree **one, struct stree **two)
687 {
688 struct smatch_state *tmp_state;
689 struct sm_state *sm;
690 struct state_list *add_to_one = NULL;
691 struct state_list *add_to_two = NULL;
692 AvlIter one_iter;
693 AvlIter two_iter;
694
695 __set_cur_stree_readonly();
696
697 avl_iter_begin(&one_iter, *one, FORWARD);
698 avl_iter_begin(&two_iter, *two, FORWARD);
699
700 for (;;) {
701 if (!one_iter.sm && !two_iter.sm)
702 break;
703 if (cmp_tracker(one_iter.sm, two_iter.sm) < 0) {
704 __set_fake_cur_stree_fast(*two);
705 __in_unmatched_hook++;
706 tmp_state = __client_unmatched_state_function(one_iter.sm);
707 __in_unmatched_hook--;
708 __pop_fake_cur_stree_fast();
709 sm = alloc_state_no_name(one_iter.sm->owner, one_iter.sm->name,
710 one_iter.sm->sym, tmp_state);
711 add_ptr_list(&add_to_two, sm);
712 avl_iter_next(&one_iter);
713 } else if (cmp_tracker(one_iter.sm, two_iter.sm) == 0) {
714 avl_iter_next(&one_iter);
715 avl_iter_next(&two_iter);
716 } else {
717 __set_fake_cur_stree_fast(*one);
718 __in_unmatched_hook++;
719 tmp_state = __client_unmatched_state_function(two_iter.sm);
720 __in_unmatched_hook--;
721 __pop_fake_cur_stree_fast();
722 sm = alloc_state_no_name(two_iter.sm->owner, two_iter.sm->name,
723 two_iter.sm->sym, tmp_state);
724 add_ptr_list(&add_to_one, sm);
725 avl_iter_next(&two_iter);
726 }
727 }
728
729 __set_cur_stree_writable();
730
731 FOR_EACH_PTR(add_to_one, sm) {
732 avl_insert(one, sm);
733 } END_FOR_EACH_PTR(sm);
734
735 FOR_EACH_PTR(add_to_two, sm) {
736 avl_insert(two, sm);
737 } END_FOR_EACH_PTR(sm);
738
739 free_slist(&add_to_one);
740 free_slist(&add_to_two);
741 }
742
743 static void call_pre_merge_hooks(struct stree **one, struct stree **two)
744 {
745 struct sm_state *sm, *cur;
746 struct stree *new;
747
748 __in_unmatched_hook++;
749
750 __set_fake_cur_stree_fast(*one);
751 __push_fake_cur_stree();
752 FOR_EACH_SM(*two, sm) {
753 cur = get_sm_state(sm->owner, sm->name, sm->sym);
754 if (cur == sm)
755 continue;
756 call_pre_merge_hook(cur, sm);
757 } END_FOR_EACH_SM(sm);
758 new = __pop_fake_cur_stree();
759 overwrite_stree(new, one);
760 free_stree(&new);
761 __pop_fake_cur_stree_fast();
762
763 __set_fake_cur_stree_fast(*two);
764 __push_fake_cur_stree();
765 FOR_EACH_SM(*one, sm) {
766 cur = get_sm_state(sm->owner, sm->name, sm->sym);
767 if (cur == sm)
768 continue;
769 call_pre_merge_hook(cur, sm);
770 } END_FOR_EACH_SM(sm);
771 new = __pop_fake_cur_stree();
772 overwrite_stree(new, two);
773 free_stree(&new);
774 __pop_fake_cur_stree_fast();
775
776 __in_unmatched_hook--;
777 }
778
779 static void clone_pool_havers_stree(struct stree **stree)
780 {
781 struct sm_state *sm, *tmp;
782 struct state_list *slist = NULL;
783
784 FOR_EACH_SM(*stree, sm) {
785 if (sm->pool) {
786 tmp = clone_sm(sm);
787 add_ptr_list(&slist, tmp);
788 }
789 } END_FOR_EACH_SM(sm);
790
791 FOR_EACH_PTR(slist, sm) {
792 avl_insert(stree, sm);
793 } END_FOR_EACH_PTR(sm);
794
795 free_slist(&slist);
796 }
|