absolute: fix parameter info counting
[smatch.git] / smatch_estate.c
blobd31d22d3fda7716ec06eae2a11e4ed31b2b72a80
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 long long estate_max(struct smatch_state *state)
57 return rl_max(estate_ranges(state));
60 static int rlists_equiv(struct related_list *one, struct related_list *two)
62 struct relation *one_rel;
63 struct relation *two_rel;
65 PREPARE_PTR_LIST(one, one_rel);
66 PREPARE_PTR_LIST(two, two_rel);
67 for (;;) {
68 if (!one_rel && !two_rel)
69 return 1;
70 if (!one_rel || !two_rel)
71 return 0;
72 if (one_rel->sym != two_rel->sym)
73 return 0;
74 if (strcmp(one_rel->name, two_rel->name))
75 return 0;
76 NEXT_PTR_LIST(one_rel);
77 NEXT_PTR_LIST(two_rel);
79 FINISH_PTR_LIST(two_rel);
80 FINISH_PTR_LIST(one_rel);
82 return 1;
85 int estates_equiv(struct smatch_state *one, struct smatch_state *two)
87 if (one == two)
88 return 1;
89 if (!rlists_equiv(estate_related(one), estate_related(two)))
90 return 0;
91 if (strcmp(one->name, two->name) == 0)
92 return 1;
93 return 0;
96 static struct data_info *alloc_dinfo(void)
98 struct data_info *ret;
100 ret = __alloc_data_info(0);
101 ret->related = NULL;
102 ret->type = DATA_RANGE;
103 ret->value_ranges = NULL;
104 return ret;
107 static struct data_info *alloc_dinfo_range(long long min, long long max)
109 struct data_info *ret;
111 ret = alloc_dinfo();
112 add_range(&ret->value_ranges, min, max);
113 return ret;
116 static struct data_info *alloc_dinfo_range_list(struct range_list *rl)
118 struct data_info *ret;
120 ret = alloc_dinfo();
121 ret->value_ranges = rl;
122 return ret;
125 static struct data_info *clone_dinfo(struct data_info *dinfo)
127 struct data_info *ret;
129 ret = alloc_dinfo();
130 ret->related = clone_related_list(dinfo->related);
131 ret->value_ranges = clone_range_list(dinfo->value_ranges);
132 return ret;
135 struct smatch_state *clone_estate(struct smatch_state *state)
137 struct smatch_state *ret;
139 ret = __alloc_smatch_state(0);
140 ret->name = state->name;
141 ret->data = clone_dinfo(get_dinfo(state));
142 return ret;
145 struct smatch_state *alloc_estate_empty(void)
147 struct smatch_state *state;
148 struct data_info *dinfo;
150 dinfo = alloc_dinfo();
151 state = __alloc_smatch_state(0);
152 state->data = dinfo;
153 state->name = "";
154 return state;
157 static struct smatch_state *alloc_estate_no_name(int val)
159 struct smatch_state *state;
161 state = __alloc_smatch_state(0);
162 state->data = (void *)alloc_dinfo_range(val, val);
163 return state;
166 /* We do this because ->value_ranges is a list */
167 struct smatch_state *extra_undefined(void)
169 return &estate_undefined;
172 struct smatch_state *extra_empty(void)
174 struct smatch_state *ret;
176 ret = __alloc_smatch_state(0);
177 ret->name = "empty";
178 ret->data = alloc_dinfo();
179 return ret;
182 struct smatch_state *alloc_estate(long long val)
184 struct smatch_state *state;
186 state = alloc_estate_no_name(val);
187 state->name = show_ranges(get_dinfo(state)->value_ranges);
188 return state;
191 struct smatch_state *alloc_estate_range(long long min, long long max)
193 struct smatch_state *state;
195 if (min == whole_range.min && max == whole_range.max)
196 return extra_undefined();
197 state = __alloc_smatch_state(0);
198 state->data = (void *)alloc_dinfo_range(min, max);
199 state->name = show_ranges(get_dinfo(state)->value_ranges);
200 return state;
203 struct smatch_state *alloc_estate_range_list(struct range_list *rl)
205 struct smatch_state *state;
207 if (!rl)
208 return extra_empty();
210 if (is_whole_range_rl(rl))
211 return extra_undefined();
213 state = __alloc_smatch_state(0);
214 state->data = (void *)alloc_dinfo_range_list(rl);
215 state->name = show_ranges(get_dinfo(state)->value_ranges);
216 return state;
219 void alloc_estate_undefined(void)
221 static struct data_info dinfo = {
222 .type = DATA_RANGE
225 dinfo.value_ranges = clone_permanent(whole_range_list());
226 estate_undefined.data = &dinfo;