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
)
47 e
.key
= alloc_string(look_for
);
48 hsearch_r(e
, FIND
, &ep
, &func_hash
);
50 struct call_back_list
*list
= NULL
;
52 add_ptr_list(&list
, cb
);
57 add_ptr_list((struct call_back_list
**)&ep
->data
, cb
);
60 if (!hsearch_r(e
, ENTER
, &ep
, &func_hash
)) {
61 printf("Error hash table too small in smatch_function_hooks.c\n");
67 void add_function_hook(const char *look_for
, func_hook
*call_back
, void *info
)
69 struct fcall_back
*cb
;
71 cb
= alloc_fcall_back(REGULAR_CALL
, call_back
, info
);
72 add_cb_hook(look_for
, cb
);
75 void add_conditional_hook(const char *look_for
, func_hook
*call_back
,
78 struct fcall_back
*cb
;
80 cb
= alloc_fcall_back(CONDITIONAL_CALL
, call_back
, info
);
81 add_cb_hook(look_for
, cb
);
84 void add_function_assign_hook(const char *look_for
, func_hook
*call_back
,
87 struct fcall_back
*cb
;
89 cb
= alloc_fcall_back(ASSIGN_CALL
, call_back
, info
);
90 add_cb_hook(look_for
, cb
);
93 static void call_call_backs(struct call_back_list
*list
, int type
,
94 const char *fn
, struct expression
*expr
)
96 struct fcall_back
*tmp
;
98 FOR_EACH_PTR(list
, tmp
) {
99 if (tmp
->type
== type
)
100 (tmp
->call_back
)(fn
, expr
, tmp
->info
);
101 } END_FOR_EACH_PTR(tmp
);
104 static void match_function_call(struct expression
*expr
)
106 struct call_back_list
*call_backs
;
108 if (expr
->fn
->type
!= EXPR_SYMBOL
|| !expr
->fn
->symbol
)
110 call_backs
= get_call_backs(expr
->fn
->symbol
->ident
->name
);
113 call_call_backs(call_backs
, REGULAR_CALL
, expr
->fn
->symbol
->ident
->name
,
117 void __match_initializer_call(struct symbol
*sym
)
119 struct call_back_list
*call_backs
;
120 struct expression
*initializer
= sym
->initializer
;
121 struct expression
*e_assign
, *e_symbol
;
123 if (initializer
->fn
->type
!= EXPR_SYMBOL
124 || !initializer
->fn
->symbol
)
126 call_backs
= get_call_backs(initializer
->fn
->symbol
->ident
->name
);
130 e_assign
= alloc_expression(initializer
->pos
, EXPR_ASSIGNMENT
);
131 e_symbol
= alloc_expression(initializer
->pos
, EXPR_SYMBOL
);
132 e_symbol
->symbol
= sym
;
133 e_symbol
->symbol_name
= sym
->ident
;
134 e_assign
->left
= e_symbol
;
135 e_assign
->right
= initializer
;
136 call_call_backs(call_backs
, ASSIGN_CALL
,
137 initializer
->fn
->symbol
->ident
->name
, e_assign
);
140 static void match_assign_call(struct expression
*expr
)
142 struct call_back_list
*call_backs
;
145 if (expr
->right
->fn
->type
!= EXPR_SYMBOL
|| !expr
->right
->fn
->symbol
)
147 fn
= expr
->right
->fn
->symbol
->ident
->name
;
148 call_backs
= get_call_backs(fn
);
151 call_call_backs(call_backs
, ASSIGN_CALL
, fn
, expr
);
154 static void match_conditional_call(struct expression
*expr
)
156 struct call_back_list
*call_backs
;
157 struct fcall_back
*tmp
;
161 if (expr
->type
!= EXPR_CALL
)
164 if (expr
->fn
->type
!= EXPR_SYMBOL
|| !expr
->fn
->symbol
)
167 fn
= expr
->fn
->symbol
->ident
->name
;
168 call_backs
= get_call_backs(fn
);
172 FOR_EACH_PTR(call_backs
, tmp
) {
173 if (tmp
->type
!= CONDITIONAL_CALL
)
176 (tmp
->call_back
)(fn
, expr
, tmp
->info
);
178 FOR_EACH_PTR(cond_true
, sm
) {
179 __set_true_false_sm(sm
, NULL
);
180 } END_FOR_EACH_PTR(sm
);
181 free_slist(&cond_true
);
183 FOR_EACH_PTR(cond_false
, sm
) {
184 __set_true_false_sm(NULL
, sm
);
185 } END_FOR_EACH_PTR(sm
);
186 free_slist(&cond_false
);
188 } END_FOR_EACH_PTR(tmp
);
192 void set_cond_states(const char *name
, int owner
, struct symbol
*sym
,
193 struct smatch_state
*true_state
,
194 struct smatch_state
*false_state
)
197 printf("Error: call set_true_false_states() not"
198 "set_cond_states()\n");
203 struct smatch_state
*tmp
;
205 tmp
= get_state(name
, owner
, sym
);
206 SM_DEBUG("%d set_true_false '%s'. Was %s. Now T:%s F:%s\n",
207 get_lineno(), name
, show_state(tmp
),
208 show_state(true_state
), show_state(false_state
));
212 set_state_slist(&cond_true
, name
, owner
, sym
, true_state
);
215 set_state_slist(&cond_false
, name
, owner
, sym
, false_state
);
218 void create_function_hash(void)
220 hcreate_r(10000, &func_hash
); // Apparently 1000 is too few...
223 void register_function_hooks(int id
)
225 add_hook(&match_function_call
, FUNCTION_CALL_HOOK
);
226 add_hook(&match_assign_call
, CALL_ASSIGNMENT_HOOK
);
227 add_hook(&match_conditional_call
, CONDITION_HOOK
);