sval: make sval versions of smatch_estate.c functions
[smatch.git] / smatch_estate.c
blobd13394860e6a3f697a11199ff03dc4e84c817c79
1 /*
2 * smatch/smatch_dinfo.c
4 * Copyright (C) 2010 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
8 */
11 * smatch_dinfo.c has helper functions for handling data_info structs
15 #include <stdlib.h>
16 #ifndef __USE_ISOC99
17 #define __USE_ISOC99
18 #endif
19 #include <limits.h>
20 #include "parse.h"
21 #include "smatch.h"
22 #include "smatch_slist.h"
23 #include "smatch_extra.h"
25 struct smatch_state estate_undefined = {
26 .name = "unknown"
29 struct data_info *get_dinfo(struct smatch_state *state)
31 if (!state)
32 return NULL;
33 return (struct data_info *)state->data;
36 struct range_list *estate_ranges(struct smatch_state *state)
38 if (!state)
39 return NULL;
40 return get_dinfo(state)->value_ranges;
43 struct range_list_sval *estate_ranges_sval(struct smatch_state *state)
45 if (!state)
46 return NULL;
47 return range_list_to_sval(get_dinfo(state)->value_ranges);
50 struct related_list *estate_related(struct smatch_state *state)
52 if (!state)
53 return NULL;
54 return get_dinfo(state)->related;
57 long long estate_min(struct smatch_state *state)
59 return rl_min(estate_ranges(state));
62 sval_t estate_min_sval(struct smatch_state *state)
64 return rl_min_sval(estate_ranges_sval(state));
67 long long estate_max(struct smatch_state *state)
69 return rl_max(estate_ranges(state));
72 sval_t estate_max_sval(struct smatch_state *state)
74 return rl_max_sval(estate_ranges_sval(state));
77 static int rlists_equiv(struct related_list *one, struct related_list *two)
79 struct relation *one_rel;
80 struct relation *two_rel;
82 PREPARE_PTR_LIST(one, one_rel);
83 PREPARE_PTR_LIST(two, two_rel);
84 for (;;) {
85 if (!one_rel && !two_rel)
86 return 1;
87 if (!one_rel || !two_rel)
88 return 0;
89 if (one_rel->sym != two_rel->sym)
90 return 0;
91 if (strcmp(one_rel->name, two_rel->name))
92 return 0;
93 NEXT_PTR_LIST(one_rel);
94 NEXT_PTR_LIST(two_rel);
96 FINISH_PTR_LIST(two_rel);
97 FINISH_PTR_LIST(one_rel);
99 return 1;
102 int estates_equiv(struct smatch_state *one, struct smatch_state *two)
104 if (one == two)
105 return 1;
106 if (!rlists_equiv(estate_related(one), estate_related(two)))
107 return 0;
108 if (strcmp(one->name, two->name) == 0)
109 return 1;
110 return 0;
113 static struct data_info *alloc_dinfo(void)
115 struct data_info *ret;
117 ret = __alloc_data_info(0);
118 ret->related = NULL;
119 ret->type = DATA_RANGE;
120 ret->value_ranges = NULL;
121 return ret;
124 static struct data_info *alloc_dinfo_range(long long min, long long max)
126 struct data_info *ret;
128 ret = alloc_dinfo();
129 add_range(&ret->value_ranges, min, max);
130 return ret;
133 static struct data_info *alloc_dinfo_range_list(struct range_list *rl)
135 struct data_info *ret;
137 ret = alloc_dinfo();
138 ret->value_ranges = rl;
139 return ret;
142 static struct data_info *clone_dinfo(struct data_info *dinfo)
144 struct data_info *ret;
146 ret = alloc_dinfo();
147 ret->related = clone_related_list(dinfo->related);
148 ret->value_ranges = clone_range_list(dinfo->value_ranges);
149 return ret;
152 struct smatch_state *clone_estate(struct smatch_state *state)
154 struct smatch_state *ret;
156 ret = __alloc_smatch_state(0);
157 ret->name = state->name;
158 ret->data = clone_dinfo(get_dinfo(state));
159 return ret;
162 struct smatch_state *alloc_estate_empty(void)
164 struct smatch_state *state;
165 struct data_info *dinfo;
167 dinfo = alloc_dinfo();
168 state = __alloc_smatch_state(0);
169 state->data = dinfo;
170 state->name = "";
171 return state;
174 static struct smatch_state *alloc_estate_no_name(int val)
176 struct smatch_state *state;
178 state = __alloc_smatch_state(0);
179 state->data = (void *)alloc_dinfo_range(val, val);
180 return state;
183 /* We do this because ->value_ranges is a list */
184 struct smatch_state *extra_undefined(void)
186 return &estate_undefined;
189 struct smatch_state *extra_empty(void)
191 struct smatch_state *ret;
193 ret = __alloc_smatch_state(0);
194 ret->name = "empty";
195 ret->data = alloc_dinfo();
196 return ret;
199 struct smatch_state *alloc_estate(long long val)
201 struct smatch_state *state;
203 state = alloc_estate_no_name(val);
204 state->name = show_ranges(get_dinfo(state)->value_ranges);
205 return state;
208 struct smatch_state *alloc_estate_sval(sval_t sval)
210 struct smatch_state *state;
212 state = alloc_estate_no_name(sval.value);
213 state->name = show_ranges(get_dinfo(state)->value_ranges);
214 return state;
217 struct smatch_state *alloc_estate_range(long long min, long long max)
219 struct smatch_state *state;
221 if (min == whole_range.min && max == whole_range.max)
222 return extra_undefined();
223 state = __alloc_smatch_state(0);
224 state->data = (void *)alloc_dinfo_range(min, max);
225 state->name = show_ranges(get_dinfo(state)->value_ranges);
226 return state;
229 struct smatch_state *alloc_estate_range_sval(sval_t min, sval_t max)
231 struct smatch_state *state;
233 if (sval_is_min(min) && sval_is_max(max))
234 return extra_undefined();
235 state = __alloc_smatch_state(0);
236 state->data = (void *)alloc_dinfo_range(min.value, max.value);
237 state->name = show_ranges(get_dinfo(state)->value_ranges);
238 return state;
241 struct smatch_state *alloc_estate_range_list(struct range_list *rl)
243 struct smatch_state *state;
245 if (!rl)
246 return extra_empty();
248 if (is_whole_range_rl(rl))
249 return extra_undefined();
251 state = __alloc_smatch_state(0);
252 state->data = (void *)alloc_dinfo_range_list(rl);
253 state->name = show_ranges(get_dinfo(state)->value_ranges);
254 return state;
257 struct smatch_state *alloc_estate_range_list_sval(struct range_list_sval *rl)
259 struct smatch_state *state;
261 if (!rl)
262 return extra_empty();
264 state = __alloc_smatch_state(0);
265 state->data = (void *)alloc_dinfo_range_list(rl_sval_to_rl(rl));
266 state->name = show_ranges_sval(rl);
267 return state;
270 void alloc_estate_undefined(void)
272 static struct data_info dinfo = {
273 .type = DATA_RANGE
276 dinfo.value_ranges = clone_permanent(whole_range_list());
277 estate_undefined.data = &dinfo;