6 #include "smatch_slist.h"
8 ALLOCATOR(fcall_back
, "call backs");
10 static struct hsearch_data func_hash
;
12 static struct state_list
*cond_true
= NULL
;
13 static struct state_list
*cond_false
= NULL
;
14 static int in_hook
= 0;
15 #define REGULAR_CALL 0
16 #define CONDITIONAL_CALL 1
19 static struct fcall_back
*alloc_fcall_back(int type
, func_hook
*call_back
,
22 struct fcall_back
*cb
;
24 cb
= __alloc_fcall_back(0);
26 cb
->call_back
= call_back
;
31 static struct call_back_list
*get_call_backs(const char *look_for
)
35 e
.key
= (char *)look_for
;
36 hsearch_r(e
, FIND
, &ep
, &func_hash
);
39 return (struct call_back_list
*)ep
->data
;
42 static void add_cb_hook(const char *look_for
, struct fcall_back
*cb
)
46 e
.key
= alloc_string(look_for
);
47 hsearch_r(e
, FIND
, &ep
, &func_hash
);
49 struct call_back_list
*list
= NULL
;
51 add_ptr_list(&list
, cb
);
55 add_ptr_list((struct call_back_list
**)&ep
->data
, cb
);
58 if (!hsearch_r(e
, ENTER
, &ep
, &func_hash
)) {
59 printf("Error hash table too small in smatch_function_hooks.c\n");
64 void add_function_hook(const char *look_for
, func_hook
*call_back
, void *info
)
66 struct fcall_back
*cb
;
68 cb
= alloc_fcall_back(REGULAR_CALL
, call_back
, info
);
69 add_cb_hook(look_for
, cb
);
72 void add_conditional_hook(const char *look_for
, func_hook
*call_back
,
75 struct fcall_back
*cb
;
77 cb
= alloc_fcall_back(CONDITIONAL_CALL
, call_back
, info
);
78 add_cb_hook(look_for
, cb
);
81 void add_function_assign_hook(const char *look_for
, func_hook
*call_back
,
84 struct fcall_back
*cb
;
86 cb
= alloc_fcall_back(ASSIGN_CALL
, call_back
, info
);
87 add_cb_hook(look_for
, cb
);
90 static void call_call_backs(struct call_back_list
*list
, int type
,
91 const char *fn
, struct expression
*expr
)
93 struct fcall_back
*tmp
;
95 FOR_EACH_PTR(list
, tmp
) {
96 if (tmp
->type
== type
)
97 (tmp
->call_back
)(fn
, expr
, tmp
->info
);
98 } END_FOR_EACH_PTR(tmp
);
101 static void match_function_call(struct expression
*expr
)
103 struct call_back_list
*call_backs
;
105 if (expr
->fn
->type
!= EXPR_SYMBOL
|| !expr
->fn
->symbol
)
107 call_backs
= get_call_backs(expr
->fn
->symbol
->ident
->name
);
110 call_call_backs(call_backs
, REGULAR_CALL
, expr
->fn
->symbol
->ident
->name
,
114 void __match_initializer_call(struct symbol
*sym
)
116 struct call_back_list
*call_backs
;
117 struct expression
*initializer
= sym
->initializer
;
118 struct expression
*e_assign
, *e_symbol
;
120 if (initializer
->fn
->type
!= EXPR_SYMBOL
121 || !initializer
->fn
->symbol
)
123 call_backs
= get_call_backs(initializer
->fn
->symbol
->ident
->name
);
127 e_assign
= alloc_expression(initializer
->pos
, EXPR_ASSIGNMENT
);
128 e_symbol
= alloc_expression(initializer
->pos
, EXPR_SYMBOL
);
129 e_symbol
->symbol
= sym
;
130 e_symbol
->symbol_name
= sym
->ident
;
131 e_assign
->left
= e_symbol
;
132 e_assign
->right
= initializer
;
133 call_call_backs(call_backs
, ASSIGN_CALL
,
134 initializer
->fn
->symbol
->ident
->name
, e_assign
);
137 static void match_assign_call(struct expression
*expr
)
139 struct call_back_list
*call_backs
;
142 if (expr
->right
->fn
->type
!= EXPR_SYMBOL
|| !expr
->right
->fn
->symbol
)
144 fn
= expr
->right
->fn
->symbol
->ident
->name
;
145 call_backs
= get_call_backs(fn
);
148 call_call_backs(call_backs
, ASSIGN_CALL
, fn
, expr
);
151 static void match_conditional_call(struct expression
*expr
)
153 struct call_back_list
*call_backs
;
154 struct fcall_back
*tmp
;
158 if (expr
->type
!= EXPR_CALL
)
161 if (expr
->fn
->type
!= EXPR_SYMBOL
|| !expr
->fn
->symbol
)
164 fn
= expr
->fn
->symbol
->ident
->name
;
165 call_backs
= get_call_backs(fn
);
169 FOR_EACH_PTR(call_backs
, tmp
) {
170 if (tmp
->type
!= CONDITIONAL_CALL
)
173 (tmp
->call_back
)(fn
, expr
, tmp
->info
);
175 FOR_EACH_PTR(cond_true
, sm
) {
176 __set_true_false_sm(sm
, NULL
);
177 } END_FOR_EACH_PTR(sm
);
178 free_slist(&cond_true
);
180 FOR_EACH_PTR(cond_false
, sm
) {
181 __set_true_false_sm(NULL
, sm
);
182 } END_FOR_EACH_PTR(sm
);
183 free_slist(&cond_false
);
185 } END_FOR_EACH_PTR(tmp
);
189 void set_cond_states(const char *name
, int owner
, struct symbol
*sym
,
190 struct smatch_state
*true_state
,
191 struct smatch_state
*false_state
)
194 printf("Error: call set_true_false_states() not"
195 "set_cond_states()\n");
200 struct smatch_state
*tmp
;
202 tmp
= get_state(name
, owner
, sym
);
203 SM_DEBUG("%d set_true_false '%s'. Was %s. Now T:%s F:%s\n",
204 get_lineno(), name
, show_state(tmp
),
205 show_state(true_state
), show_state(false_state
));
209 set_state_slist(&cond_true
, name
, owner
, sym
, true_state
);
212 set_state_slist(&cond_false
, name
, owner
, sym
, false_state
);
215 void create_function_hash(void)
217 hcreate_r(10000, &func_hash
); // Apparently 1000 is too few...
220 void register_function_hooks(int id
)
222 add_hook(&match_function_call
, FUNCTION_CALL_HOOK
);
223 add_hook(&match_assign_call
, CALL_ASSIGNMENT_HOOK
);
224 add_hook(&match_conditional_call
, CONDITION_HOOK
);