db: caller_info: fix more fall out
[smatch.git] / smatch_estate.c
blob6df31b8170729c5e1b9bd530725884986cc1d076
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;
37 struct range_list *estate_ranges(struct smatch_state *state)
39 if (!state)
40 return NULL;
41 return get_dinfo(state)->value_ranges;
44 struct related_list *estate_related(struct smatch_state *state)
46 if (!state)
47 return NULL;
48 return get_dinfo(state)->related;
51 long long estate_min(struct smatch_state *state)
53 return rl_min(estate_ranges(state));
56 long long estate_max(struct smatch_state *state)
58 return rl_max(estate_ranges(state));
61 static int rlists_equiv(struct related_list *one, struct related_list *two)
63 struct relation *one_rel;
64 struct relation *two_rel;
66 PREPARE_PTR_LIST(one, one_rel);
67 PREPARE_PTR_LIST(two, two_rel);
68 for (;;) {
69 if (!one_rel && !two_rel)
70 return 1;
71 if (!one_rel || !two_rel)
72 return 0;
73 if (one_rel->sym != two_rel->sym)
74 return 0;
75 if (strcmp(one_rel->name, two_rel->name))
76 return 0;
77 NEXT_PTR_LIST(one_rel);
78 NEXT_PTR_LIST(two_rel);
80 FINISH_PTR_LIST(two_rel);
81 FINISH_PTR_LIST(one_rel);
83 return 1;
86 int estates_equiv(struct smatch_state *one, struct smatch_state *two)
88 if (one == two)
89 return 1;
90 if (!rlists_equiv(estate_related(one), estate_related(two)))
91 return 0;
92 if (strcmp(one->name, two->name) == 0)
93 return 1;
94 return 0;
97 static struct data_info *alloc_dinfo(void)
99 struct data_info *ret;
101 ret = __alloc_data_info(0);
102 ret->related = NULL;
103 ret->type = DATA_RANGE;
104 ret->value_ranges = NULL;
105 return ret;
108 static struct data_info *alloc_dinfo_range(long long min, long long max)
110 struct data_info *ret;
112 ret = alloc_dinfo();
113 add_range(&ret->value_ranges, min, max);
114 return ret;
117 static struct data_info *alloc_dinfo_range_list(struct range_list *rl)
119 struct data_info *ret;
121 ret = alloc_dinfo();
122 ret->value_ranges = rl;
123 return ret;
126 static struct data_info *clone_dinfo(struct data_info *dinfo)
128 struct data_info *ret;
130 ret = alloc_dinfo();
131 ret->related = clone_related_list(dinfo->related);
132 ret->value_ranges = clone_range_list(dinfo->value_ranges);
133 return ret;
136 struct smatch_state *clone_estate(struct smatch_state *state)
138 struct smatch_state *ret;
140 ret = __alloc_smatch_state(0);
141 ret->name = state->name;
142 ret->data = clone_dinfo(get_dinfo(state));
143 return ret;
146 struct smatch_state *alloc_estate_empty(void)
148 struct smatch_state *state;
149 struct data_info *dinfo;
151 dinfo = alloc_dinfo();
152 state = __alloc_smatch_state(0);
153 state->data = dinfo;
154 state->name = "";
155 return state;
158 static struct smatch_state *alloc_estate_no_name(int val)
160 struct smatch_state *state;
162 state = __alloc_smatch_state(0);
163 state->data = (void *)alloc_dinfo_range(val, val);
164 return state;
167 /* We do this because ->value_ranges is a list */
168 struct smatch_state *extra_undefined(void)
170 return &estate_undefined;
173 struct smatch_state *extra_empty(void)
175 struct smatch_state *ret;
177 ret = __alloc_smatch_state(0);
178 ret->name = "empty";
179 ret->data = alloc_dinfo();
180 return ret;
183 struct smatch_state *alloc_estate(long long val)
185 struct smatch_state *state;
187 state = alloc_estate_no_name(val);
188 state->name = show_ranges(get_dinfo(state)->value_ranges);
189 return state;
192 struct smatch_state *alloc_estate_range(long long min, long long max)
194 struct smatch_state *state;
196 if (min == whole_range.min && max == whole_range.max)
197 return extra_undefined();
198 state = __alloc_smatch_state(0);
199 state->data = (void *)alloc_dinfo_range(min, max);
200 state->name = show_ranges(get_dinfo(state)->value_ranges);
201 return state;
204 struct smatch_state *alloc_estate_range_list(struct range_list *rl)
206 struct smatch_state *state;
208 if (!rl)
209 return extra_empty();
211 if (is_whole_range_rl(rl))
212 return extra_undefined();
214 state = __alloc_smatch_state(0);
215 state->data = (void *)alloc_dinfo_range_list(rl);
216 state->name = show_ranges(get_dinfo(state)->value_ranges);
217 return state;
220 void alloc_estate_undefined(void)
222 static struct data_info dinfo = {
223 .type = DATA_RANGE
226 dinfo.value_ranges = clone_permanent(whole_range_list());
227 estate_undefined.data = &dinfo;