Make cur_slist static. It's only used in smatch_states.c.
[smatch.git] / smatch_slist.c
blob71f3769793395ae5bb2196566e452dbde04d634f
1 /*
2 * sparse/smatch_slist.c
4 * Copyright (C) 2008 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
8 */
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include "smatch.h"
13 #include "smatch.h"
14 #include "smatch_slist.h"
16 ALLOCATOR(sm_state, "smatch state");
17 ALLOCATOR(named_slist, "named slist");
19 void add_history(struct sm_state *state)
21 struct state_history *tmp;
23 if (!state)
24 return;
25 tmp = malloc(sizeof(*tmp));
26 tmp->loc = get_lineno();
27 add_ptr_list(&state->line_history, tmp);
30 struct sm_state *alloc_state(const char *name, int owner,
31 struct symbol *sym, struct smatch_state *state)
33 struct sm_state *sm_state = __alloc_sm_state(0);
35 sm_state->name = (char *)name;
36 sm_state->owner = owner;
37 sm_state->sym = sym;
38 sm_state->state = state;
39 sm_state->line_history = NULL;
40 sm_state->path_history = NULL;
41 add_history(sm_state);
42 return sm_state;
45 struct sm_state *clone_state(struct sm_state *s)
47 return alloc_state(s->name, s->owner, s->sym, s->state);
50 struct state_list *clone_slist(struct state_list *from_slist)
52 struct sm_state *state;
53 struct sm_state *tmp;
54 struct state_list *to_slist = NULL;
56 FOR_EACH_PTR(from_slist, state) {
57 tmp = clone_state(state);
58 add_ptr_list(&to_slist, tmp);
59 } END_FOR_EACH_PTR(state);
60 return to_slist;
63 struct smatch_state *merge_states(const char *name, int owner,
64 struct symbol *sym,
65 struct smatch_state *state1,
66 struct smatch_state *state2)
68 struct smatch_state *ret;
70 if (state1 == state2)
71 ret = state1;
72 else if (__has_merge_function(owner))
73 ret = __client_merge_function(owner, name, sym, state1, state2);
74 else
75 ret = &undefined;
77 SM_DEBUG("%d merge name='%s' owner=%d: %s + %s => %s\n",
78 get_lineno(), name, owner, show_state(state1),
79 show_state(state2), show_state(ret));
81 return ret;
84 void merge_state_slist(struct state_list **slist, const char *name, int owner,
85 struct symbol *sym, struct smatch_state *state)
87 struct sm_state *tmp;
88 struct smatch_state *s;
90 FOR_EACH_PTR(*slist, tmp) {
91 if (tmp->owner == owner && tmp->sym == sym
92 && !strcmp(tmp->name, name)){
93 s = merge_states(name, owner, sym, tmp->state, state);
94 if (tmp->state != s) {
95 add_history(tmp);
97 tmp->state = s;
98 return;
100 } END_FOR_EACH_PTR(tmp);
101 tmp = alloc_state(name, owner, sym, state);
102 add_state_slist(slist, tmp);
105 struct smatch_state *get_state_slist(struct state_list *slist, const char *name, int owner,
106 struct symbol *sym)
108 struct sm_state *state;
110 if (!name)
111 return NULL;
113 FOR_EACH_PTR(slist, state) {
114 if (state->owner == owner && state->sym == sym
115 && !strcmp(state->name, name))
116 return state->state;
117 } END_FOR_EACH_PTR(state);
118 return NULL;
121 void add_state_slist(struct state_list **slist, struct sm_state *state)
123 add_ptr_list(slist, state);
126 void set_state_slist(struct state_list **slist, const char *name, int owner,
127 struct symbol *sym, struct smatch_state *state)
129 struct sm_state *tmp;
131 FOR_EACH_PTR(*slist, tmp) {
132 if (tmp->owner == owner && tmp->sym == sym
133 && !strcmp(tmp->name, name)){
134 tmp->state = state;
135 return;
137 } END_FOR_EACH_PTR(tmp);
138 tmp = alloc_state(name, owner, sym, state);
139 add_state_slist(slist, tmp);
142 void delete_state_slist(struct state_list **slist, const char *name, int owner,
143 struct symbol *sym)
145 struct sm_state *state;
147 FOR_EACH_PTR(*slist, state) {
148 if (state->owner == owner && state->sym == sym
149 && !strcmp(state->name, name)){
150 delete_ptr_list_entry((struct ptr_list **)slist,
151 state, 1);
152 __free_sm_state(state);
153 return;
155 } END_FOR_EACH_PTR(state);
159 void push_slist(struct state_list_stack **list_stack, struct state_list *slist)
161 add_ptr_list(list_stack, slist);
164 struct state_list *pop_slist(struct state_list_stack **list_stack)
166 struct state_list *slist;
168 slist = last_ptr_list((struct ptr_list *)*list_stack);
169 delete_ptr_list_last((struct ptr_list **)list_stack);
170 return slist;
173 void del_slist(struct state_list **slist)
175 __free_ptr_list((struct ptr_list **)slist);
178 void del_slist_stack(struct state_list_stack **slist_stack)
180 struct state_list *slist;
182 FOR_EACH_PTR(*slist_stack, slist) {
183 __free_ptr_list((struct ptr_list **)&slist);
184 } END_FOR_EACH_PTR(slist);
185 __free_ptr_list((struct ptr_list **)slist_stack);
189 * set_state_stack() sets the state for the top slist on the stack.
191 void set_state_stack(struct state_list_stack **stack, const char *name,
192 int owner, struct symbol *sym, struct smatch_state *state)
194 struct state_list *slist;
196 slist = pop_slist(stack);
197 set_state_slist(&slist, name, owner, sym, state);
198 push_slist(stack, slist);
202 * get_state_stack() gets the state for the top slist on the stack.
204 struct smatch_state *get_state_stack(struct state_list_stack *stack,
205 const char *name, int owner,
206 struct symbol *sym)
208 struct state_list *slist;
209 struct smatch_state *ret;
211 slist = pop_slist(&stack);
212 ret = get_state_slist(slist, name, owner, sym);
213 push_slist(&stack, slist);
214 return ret;
217 void merge_state_stack(struct state_list_stack **stack, const char *name,
218 int owner, struct symbol *sym,
219 struct smatch_state *state)
221 struct state_list *slist;
223 slist = pop_slist(stack);
224 merge_state_slist(&slist, name, owner, sym, state);
225 push_slist(stack, slist);
228 void merge_slist(struct state_list **to, struct state_list *slist)
230 struct sm_state *state;
232 if (!slist) {
233 return;
236 FOR_EACH_PTR(slist, state) {
237 merge_state_slist(to, state->name, state->owner,
238 state->sym, state->state);
239 } END_FOR_EACH_PTR(state);
241 FOR_EACH_PTR(*to, state) {
242 if (!get_state_slist(slist, state->name, state->owner,
243 state->sym)) {
244 merge_state_slist(to, state->name, state->owner,
245 state->sym, NULL);
247 } END_FOR_EACH_PTR(state);
251 * and_slist_stack() ands an slist with the top slist in an slist stack.
254 void and_slist_stack(struct state_list_stack **slist_stack,
255 struct state_list *tmp_slist)
257 struct sm_state *tmp;
258 struct smatch_state *tmp_state;
260 FOR_EACH_PTR(tmp_slist, tmp) {
261 tmp_state = get_state_stack(*slist_stack, tmp->name,
262 tmp->owner, tmp->sym);
263 if (tmp_state && tmp_state != &undefined && tmp_state != tmp->state) {
264 smatch_msg("wierdness merging 'and' conditions states '%s': %s & %s.\n",
265 tmp->name, show_state(tmp_state),
266 show_state(tmp->state));
267 tmp->state = merge_states(tmp->name, tmp->owner,
268 tmp->sym, tmp->state,
269 tmp_state);
272 set_state_stack(slist_stack, tmp->name, tmp->owner, tmp->sym,
273 tmp->state);
275 } END_FOR_EACH_PTR(tmp);
276 del_slist(&tmp_slist);
279 void or_slist_stack(struct state_list_stack **slist_stack)
281 struct state_list *one;
282 struct state_list *two;
283 struct state_list *res = NULL;
284 struct sm_state *tmp;
285 struct smatch_state *s;
287 one = pop_slist(slist_stack);
288 two = pop_slist(slist_stack);
290 FOR_EACH_PTR(one, tmp) {
291 s = get_state_slist(two, tmp->name, tmp->owner, tmp->sym);
292 s = merge_states(tmp->name, tmp->owner, tmp->sym,
293 tmp->state, s);
294 set_state_slist(&res, tmp->name, tmp->owner, tmp->sym, s);
295 } END_FOR_EACH_PTR(tmp);
297 push_slist(slist_stack, res);
299 del_slist(&one);
300 del_slist(&two);
303 struct state_list *get_slist_from_slist_stack(struct slist_stack *stack,
304 const char *name)
306 struct named_slist *tmp;
308 FOR_EACH_PTR(stack, tmp) {
309 if (!strcmp(tmp->name, name))
310 return tmp->slist;
311 } END_FOR_EACH_PTR(tmp);
312 return NULL;
315 void overwrite_slist(struct state_list *from, struct state_list **to)
317 struct sm_state *tmp;
319 FOR_EACH_PTR(from, tmp) {
320 set_state_slist(to, tmp->name, tmp->owner, tmp->sym, tmp->state);
321 } END_FOR_EACH_PTR(tmp);