2 * sparse/smatch_extra_helper.c
4 * Copyright (C) 2009 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
12 #include "smatch_extra.h"
14 ALLOCATOR(data_info
, "smatch extra data");
15 __DO_ALLOCATOR(long long, sizeof(long long), __alignof__(long long), "numbers", sm_num
);
17 void print_num_list(struct num_list
*list
)
23 FOR_EACH_PTR(list
, tmp
) {
27 } END_FOR_EACH_PTR(tmp
);
31 struct data_info
*alloc_data_info(long long num
)
33 struct data_info
*ret
;
35 ret
= __alloc_data_info(0);
40 add_num(&ret
->values
, num
);
45 void add_num(struct num_list
**list
, long long num
)
50 FOR_EACH_PTR(*list
, tmp
) {
53 else if (*tmp
== num
) {
56 new = __alloc_sm_num(0);
58 INSERT_CURRENT(new, tmp
);
61 } END_FOR_EACH_PTR(tmp
);
62 new = __alloc_sm_num(0);
64 add_ptr_list(list
, new);
67 struct num_list
*clone_num_list(struct num_list
*list
)
70 struct num_list
*ret
= NULL
;
72 FOR_EACH_PTR(list
, tmp
) {
73 add_ptr_list(&ret
, tmp
);
74 } END_FOR_EACH_PTR(tmp
);
78 struct num_list
*num_list_union(struct num_list
*one
, struct num_list
*two
)
81 struct num_list
*ret
= NULL
;
83 if (!one
|| !two
) /*having nothing in a list means everything is in */
86 FOR_EACH_PTR(one
, tmp
) {
88 } END_FOR_EACH_PTR(tmp
);
89 FOR_EACH_PTR(two
, tmp
) {
91 } END_FOR_EACH_PTR(tmp
);
95 struct num_list
*num_list_intersection(struct num_list
*one
,
100 struct num_list
*ret
= NULL
;
102 PREPARE_PTR_LIST(one
, one_val
);
103 PREPARE_PTR_LIST(two
, two_val
);
105 if (!one_val
|| !two_val
)
107 if (*one_val
< *two_val
) {
108 NEXT_PTR_LIST(one_val
);
109 } else if (*one_val
== *two_val
) {
110 add_ptr_list(&ret
, one_val
);
111 NEXT_PTR_LIST(one_val
);
112 NEXT_PTR_LIST(two_val
);
114 NEXT_PTR_LIST(two_val
);
117 FINISH_PTR_LIST(two_val
);
118 FINISH_PTR_LIST(one_val
);
122 static int num_in_list(struct num_list
*list
, long long num
)
126 FOR_EACH_PTR(list
, tmp
) {
129 } END_FOR_EACH_PTR(tmp
);
133 int num_matches(struct data_info
*dinfo
, long long num
)
135 if (num_in_list(dinfo
->values
, num
))
141 * if it can be only one value return that, else return UNDEFINED
143 long long get_single_value(struct data_info
*dinfo
)
147 long long ret
= UNDEFINED
;
149 if (dinfo
->type
!= DATA_NUM
)
152 FOR_EACH_PTR(dinfo
->values
, tmp
) {
157 } END_FOR_EACH_PTR(tmp
);
161 int possibly_true(int comparison
, struct data_info
*dinfo
, int num
, int left
)
166 if (comparison
== SPECIAL_EQUAL
&& num_in_list(dinfo
->filter
, num
))
168 if (comparison
== SPECIAL_NOTEQUAL
&& num_in_list(dinfo
->filter
, num
))
174 FOR_EACH_PTR(dinfo
->values
, tmp
) {
176 ret
= true_comparison(*tmp
, comparison
, num
);
178 ret
= true_comparison(num
, comparison
, *tmp
);
181 } END_FOR_EACH_PTR(tmp
);
185 int possibly_false(int comparison
, struct data_info
*dinfo
, int num
, int left
)
190 if (comparison
== SPECIAL_EQUAL
&& num_in_list(dinfo
->filter
, num
))
193 if (comparison
== SPECIAL_NOTEQUAL
&& num_in_list(dinfo
->filter
, num
))
199 FOR_EACH_PTR(dinfo
->values
, tmp
) {
201 ret
= !true_comparison(*tmp
, comparison
, num
);
203 ret
= !true_comparison(num
, comparison
, *tmp
);
206 } END_FOR_EACH_PTR(tmp
);
210 static void free_single_dinfo(struct data_info
*dinfo
)
212 __free_ptr_list((struct ptr_list
**)&dinfo
->values
);
213 __free_ptr_list((struct ptr_list
**)&dinfo
->filter
);
216 static void free_dinfos(struct allocation_blob
*blob
)
218 unsigned int size
= sizeof(struct data_info
);
219 unsigned int offset
= 0;
221 while (offset
< blob
->offset
) {
222 free_single_dinfo((struct data_info
*)(blob
->data
+ offset
));
227 void free_data_info_allocs(void)
229 struct allocator_struct
*desc
= &data_info_allocator
;
230 struct allocation_blob
*blob
= desc
->blobs
;
233 desc
->allocations
= 0;
234 desc
->total_bytes
= 0;
235 desc
->useful_bytes
= 0;
236 desc
->freelist
= NULL
;
238 struct allocation_blob
*next
= blob
->next
;
240 blob_free(blob
, desc
->chunking
);
243 clear_sm_num_alloc();