sval: update smatch_math.c to use the new sval range functions
[smatch.git] / smatch_estate.c
blob6b60c5c8ae64bff1017059765193fd6b63e77a35
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 related_list *estate_related(struct smatch_state *state)
45 if (!state)
46 return NULL;
47 return get_dinfo(state)->related;
50 long long estate_min(struct smatch_state *state)
52 return rl_min(estate_ranges(state));
55 sval_t estate_min_sval(struct smatch_state *state)
57 return rl_min_sval(estate_ranges(state));
60 long long estate_max(struct smatch_state *state)
62 return rl_max(estate_ranges(state));
65 sval_t estate_max_sval(struct smatch_state *state)
67 return rl_max_sval(estate_ranges(state));
70 static int rlists_equiv(struct related_list *one, struct related_list *two)
72 struct relation *one_rel;
73 struct relation *two_rel;
75 PREPARE_PTR_LIST(one, one_rel);
76 PREPARE_PTR_LIST(two, two_rel);
77 for (;;) {
78 if (!one_rel && !two_rel)
79 return 1;
80 if (!one_rel || !two_rel)
81 return 0;
82 if (one_rel->sym != two_rel->sym)
83 return 0;
84 if (strcmp(one_rel->name, two_rel->name))
85 return 0;
86 NEXT_PTR_LIST(one_rel);
87 NEXT_PTR_LIST(two_rel);
89 FINISH_PTR_LIST(two_rel);
90 FINISH_PTR_LIST(one_rel);
92 return 1;
95 int estates_equiv(struct smatch_state *one, struct smatch_state *two)
97 if (one == two)
98 return 1;
99 if (!rlists_equiv(estate_related(one), estate_related(two)))
100 return 0;
101 if (strcmp(one->name, two->name) == 0)
102 return 1;
103 return 0;
106 static struct data_info *alloc_dinfo(void)
108 struct data_info *ret;
110 ret = __alloc_data_info(0);
111 ret->related = NULL;
112 ret->type = DATA_RANGE;
113 ret->value_ranges = NULL;
114 return ret;
117 static struct data_info *alloc_dinfo_range(long long min, long long max)
119 struct data_info *ret;
121 ret = alloc_dinfo();
122 add_range(&ret->value_ranges, min, max);
123 return ret;
126 static struct data_info *alloc_dinfo_range_list(struct range_list *rl)
128 struct data_info *ret;
130 ret = alloc_dinfo();
131 ret->value_ranges = rl;
132 return ret;
135 static struct data_info *clone_dinfo(struct data_info *dinfo)
137 struct data_info *ret;
139 ret = alloc_dinfo();
140 ret->related = clone_related_list(dinfo->related);
141 ret->value_ranges = clone_range_list(dinfo->value_ranges);
142 return ret;
145 struct smatch_state *clone_estate(struct smatch_state *state)
147 struct smatch_state *ret;
149 ret = __alloc_smatch_state(0);
150 ret->name = state->name;
151 ret->data = clone_dinfo(get_dinfo(state));
152 return ret;
155 struct smatch_state *alloc_estate_empty(void)
157 struct smatch_state *state;
158 struct data_info *dinfo;
160 dinfo = alloc_dinfo();
161 state = __alloc_smatch_state(0);
162 state->data = dinfo;
163 state->name = "";
164 return state;
167 static struct smatch_state *alloc_estate_no_name(int val)
169 struct smatch_state *state;
171 state = __alloc_smatch_state(0);
172 state->data = (void *)alloc_dinfo_range(val, val);
173 return state;
176 /* We do this because ->value_ranges is a list */
177 struct smatch_state *extra_undefined(void)
179 return &estate_undefined;
182 struct smatch_state *extra_empty(void)
184 struct smatch_state *ret;
186 ret = __alloc_smatch_state(0);
187 ret->name = "empty";
188 ret->data = alloc_dinfo();
189 return ret;
192 struct smatch_state *alloc_estate(long long val)
194 struct smatch_state *state;
196 state = alloc_estate_no_name(val);
197 state->name = show_ranges(get_dinfo(state)->value_ranges);
198 return state;
201 struct smatch_state *alloc_estate_range(long long min, long long max)
203 struct smatch_state *state;
205 if (min == whole_range.min && max == whole_range.max)
206 return extra_undefined();
207 state = __alloc_smatch_state(0);
208 state->data = (void *)alloc_dinfo_range(min, max);
209 state->name = show_ranges(get_dinfo(state)->value_ranges);
210 return state;
213 struct smatch_state *alloc_estate_range_list(struct range_list *rl)
215 struct smatch_state *state;
217 if (!rl)
218 return extra_empty();
220 if (is_whole_range_rl(rl))
221 return extra_undefined();
223 state = __alloc_smatch_state(0);
224 state->data = (void *)alloc_dinfo_range_list(rl);
225 state->name = show_ranges(get_dinfo(state)->value_ranges);
226 return state;
229 void alloc_estate_undefined(void)
231 static struct data_info dinfo = {
232 .type = DATA_RANGE
235 dinfo.value_ranges = clone_permanent(whole_range_list());
236 estate_undefined.data = &dinfo;