2 * sparse/smatch_ranges.c
4 * Copyright (C) 2009 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
12 #include "smatch_extra.h"
13 #include "smatch_slist.h"
15 ALLOCATOR(data_info
, "smatch extra data");
16 ALLOCATOR(data_range
, "data range");
17 __DO_ALLOCATOR(struct data_range
, sizeof(struct data_range
), __alignof__(struct data_range
),
18 "permanent ranges", perm_data_range
);
19 ALLOCATOR(data_range_sval
, "data range sval");
20 __DO_ALLOCATOR(struct data_range_sval
, sizeof(struct data_range_sval
), __alignof__(struct data_range_sval
),
21 "permanent ranges sval", perm_data_range_sval
);
23 struct data_range whole_range
= {
28 static char *show_num(long long num
)
30 static char buff
[256];
32 if (num
== whole_range
.min
)
33 snprintf(buff
, 255, "min");
34 else if (num
== whole_range
.max
)
35 snprintf(buff
, 255, "max");
37 snprintf(buff
, 255, "(%lld)", num
);
39 snprintf(buff
, 255, "%lld", num
);
45 char *show_ranges(struct range_list
*list
)
47 struct data_range
*tmp
;
53 FOR_EACH_PTR(list
, tmp
) {
55 strncat(full
, ",", 254 - strlen(full
));
56 if (tmp
->min
== tmp
->max
) {
57 strncat(full
, show_num(tmp
->min
), 254 - strlen(full
));
60 strncat(full
, show_num(tmp
->min
), 254 - strlen(full
));
61 strncat(full
, "-", 254 - strlen(full
));
62 strncat(full
, show_num(tmp
->max
), 254 - strlen(full
));
63 } END_FOR_EACH_PTR(tmp
);
64 return alloc_sname(full
);
67 void get_value_ranges(char *value
, struct range_list
**rl
)
81 if (!strncmp(start
, "max", 3)) {
84 } else if (!strncmp(start
, "u64max", 6)) {
85 val1
= LLONG_MAX
; // FIXME
87 } else if (!strncmp(start
, "s64max", 6)) {
90 } else if (!strncmp(start
, "u32max", 6)) {
93 } else if (!strncmp(start
, "s32max", 6)) {
96 } else if (!strncmp(start
, "u16max", 6)) {
99 } else if (!strncmp(start
, "s16max", 6)) {
102 } else if (!strncmp(start
, "min", 3)) {
105 } else if (!strncmp(start
, "s64min", 6)) {
108 } else if (!strncmp(start
, "s32min", 6)) {
111 } else if (!strncmp(start
, "s16min", 6)) {
115 while (*c
&& *c
!= ',' && *c
!= '-')
117 val1
= strtoll(start
, &c
, 10);
122 add_range(rl
, val1
, val1
);
126 add_range(rl
, val1
, val1
);
131 c
++; /* skip the dash in eg. 4-5 */
135 if (!strncmp(start
, "max", 3)) {
140 while (*c
&& *c
!= ',' && *c
!= '-')
142 val2
= strtoll(start
, &c
, 10);
144 add_range(rl
, val1
, val2
);
149 c
++; /* skip the comma in eg: 4-5,7 */
153 void get_value_ranges_sval(char *value
, struct range_list_sval
**rl
)
155 struct range_list
*tmp_rl
= NULL
;
157 get_value_ranges(value
, &tmp_rl
);
158 *rl
= range_list_to_sval(tmp_rl
);
161 static struct data_range range_zero
= {
166 static struct data_range range_one
= {
171 int is_whole_range_rl(struct range_list
*rl
)
173 struct data_range
*drange
;
175 if (ptr_list_empty(rl
))
177 drange
= first_ptr_list((struct ptr_list
*)rl
);
178 if (drange
->min
== whole_range
.min
&& drange
->max
== whole_range
.max
)
183 int is_whole_range_rl_sval(struct range_list_sval
*rl
)
185 struct data_range_sval
*drange
;
187 if (ptr_list_empty(rl
))
189 drange
= first_ptr_list((struct ptr_list
*)rl
);
190 if (sval_is_min(drange
->min
) && sval_is_max(drange
->max
))
195 int rl_contiguous(struct range_list
*rl
)
197 if (first_ptr_list((struct ptr_list
*)rl
) == last_ptr_list((struct ptr_list
*)rl
))
202 long long rl_min(struct range_list
*rl
)
204 struct data_range
*drange
;
206 if (ptr_list_empty(rl
))
207 return whole_range
.min
;
208 drange
= first_ptr_list((struct ptr_list
*)rl
);
212 sval_t
rl_min_sval(struct range_list
*rl
)
214 struct data_range
*drange
;
217 ret
.type
= &llong_ctype
;
218 ret
.value
= LLONG_MIN
;
219 if (ptr_list_empty(rl
))
221 drange
= first_ptr_list((struct ptr_list
*)rl
);
222 ret
.value
= drange
->min
;
226 long long rl_max(struct range_list
*rl
)
228 struct data_range
*drange
;
230 if (ptr_list_empty(rl
))
231 return whole_range
.max
;
232 drange
= last_ptr_list((struct ptr_list
*)rl
);
236 sval_t
rl_max_sval(struct range_list
*rl
)
238 struct data_range
*drange
;
241 ret
.type
= &llong_ctype
;
242 ret
.value
= LLONG_MAX
;
243 if (ptr_list_empty(rl
))
245 drange
= last_ptr_list((struct ptr_list
*)rl
);
246 ret
.value
= drange
->max
;
250 static struct data_range
*alloc_range_helper(long long min
, long long max
, int perm
)
252 struct data_range
*ret
;
255 // sm_msg("debug invalid range %lld to %lld", min, max);
256 min
= whole_range
.min
;
257 max
= whole_range
.max
;
259 if (min
== whole_range
.min
&& max
== whole_range
.max
)
261 if (min
== 0 && max
== 0)
263 if (min
== 1 && max
== 1)
267 ret
= __alloc_perm_data_range(0);
269 ret
= __alloc_data_range(0);
275 static struct data_range_sval
*alloc_range_helper_sval(sval_t min
, sval_t max
, int perm
)
277 struct data_range_sval
*ret
;
279 if (sval_cmp(min
, max
) > 0) {
280 // sm_msg("debug invalid range %lld to %lld", min, max);
281 min
.value
= LLONG_MIN
; /* fixme: need a way to represent unknown svals */
282 max
.value
= LLONG_MAX
;
286 ret
= __alloc_perm_data_range_sval(0);
288 ret
= __alloc_data_range_sval(0);
294 struct data_range
*alloc_range(long long min
, long long max
)
296 return alloc_range_helper(min
, max
, 0);
299 struct data_range_sval
*alloc_range_sval(sval_t min
, sval_t max
)
301 return alloc_range_helper_sval(min
, max
, 0);
304 struct data_range_sval
*drange_to_drange_sval(struct data_range
*drange
)
306 return alloc_range_helper_sval(ll_to_sval(drange
->min
), ll_to_sval(drange
->max
), 0);
309 struct data_range
*drange_sval_to_drange(struct data_range_sval
*drange
)
311 return alloc_range_helper(sval_to_ll(drange
->min
), sval_to_ll(drange
->max
), 0);
314 struct data_range
*alloc_range_perm(long long min
, long long max
)
316 return alloc_range_helper(min
, max
, 1);
319 struct data_range_sval
*alloc_range_perm_sval(sval_t min
, sval_t max
)
321 return alloc_range_helper_sval(min
, max
, 1);
324 struct range_list
*alloc_range_list(long long min
, long long max
)
326 struct range_list
*rl
= NULL
;
328 add_range(&rl
, min
, max
);
332 struct range_list_sval
*alloc_range_list_sval(sval_t min
, sval_t max
)
334 struct range_list_sval
*rl
= NULL
;
336 add_range_sval(&rl
, min
, max
);
340 struct range_list
*whole_range_list(void)
342 return alloc_range_list(whole_range
.min
, whole_range
.max
);
345 void add_range(struct range_list
**list
, long long min
, long long max
)
347 struct data_range
*tmp
= NULL
;
348 struct data_range
*new = NULL
;
352 * FIXME: This has a problem merging a range_list like: min-0,3-max
353 * with a range like 1-2. You end up with min-2,3-max instead of
356 FOR_EACH_PTR(*list
, tmp
) {
358 /* Sometimes we overlap with more than one range
359 so we have to delete or modify the next range. */
360 if (max
+ 1 == tmp
->min
) {
361 /* join 2 ranges here */
363 DELETE_CURRENT_PTR(tmp
);
367 /* Doesn't overlap with the next one. */
370 /* Partially overlaps with the next one. */
371 if (max
< tmp
->max
) {
375 /* Completely overlaps with the next one. */
376 if (max
>= tmp
->max
) {
377 DELETE_CURRENT_PTR(tmp
);
378 /* there could be more ranges to delete */
382 if (max
!= whole_range
.max
&& max
+ 1 == tmp
->min
) {
383 /* join 2 ranges into a big range */
384 new = alloc_range(min
, tmp
->max
);
385 REPLACE_CURRENT_PTR(tmp
, new);
388 if (max
< tmp
->min
) { /* new range entirely below */
389 new = alloc_range(min
, max
);
390 INSERT_CURRENT(new, tmp
);
393 if (min
< tmp
->min
) { /* new range partially below */
398 new = alloc_range(min
, max
);
399 REPLACE_CURRENT_PTR(tmp
, new);
404 if (max
<= tmp
->max
) /* new range already included */
406 if (min
<= tmp
->max
) { /* new range partially above */
408 new = alloc_range(min
, max
);
409 REPLACE_CURRENT_PTR(tmp
, new);
413 if (min
!= whole_range
.min
&& min
- 1 == tmp
->max
) {
414 /* join 2 ranges into a big range */
415 new = alloc_range(tmp
->min
, max
);
416 REPLACE_CURRENT_PTR(tmp
, new);
420 /* the new range is entirely above the existing ranges */
421 } END_FOR_EACH_PTR(tmp
);
424 new = alloc_range(min
, max
);
425 add_ptr_list(list
, new);
428 void add_range_sval(struct range_list_sval
**list
, sval_t min
, sval_t max
)
430 struct data_range_sval
*tmp
= NULL
;
431 struct data_range_sval
*new = NULL
;
435 * FIXME: This has a problem merging a range_list like: min-0,3-max
436 * with a range like 1-2. You end up with min-2,3-max instead of
439 FOR_EACH_PTR(*list
, tmp
) {
441 /* Sometimes we overlap with more than one range
442 so we have to delete or modify the next range. */
443 if (max
.value
+ 1 == tmp
->min
.value
) {
444 /* join 2 ranges here */
446 DELETE_CURRENT_PTR(tmp
);
450 /* Doesn't overlap with the next one. */
451 if (sval_cmp(max
, tmp
->min
) < 0)
453 /* Partially overlaps with the next one. */
454 if (sval_cmp(max
, tmp
->max
) < 0) {
455 tmp
->min
.value
= max
.value
+ 1;
458 /* Completely overlaps with the next one. */
459 if (sval_cmp(max
, tmp
->max
) >= 0) {
460 DELETE_CURRENT_PTR(tmp
);
461 /* there could be more ranges to delete */
465 if (max
.value
+ 1 == tmp
->min
.value
) {
466 /* join 2 ranges into a big range */
467 new = alloc_range_sval(min
, tmp
->max
);
468 REPLACE_CURRENT_PTR(tmp
, new);
471 if (sval_cmp(max
, tmp
->min
)) { /* new range entirely below */
472 new = alloc_range_sval(min
, max
);
473 INSERT_CURRENT(new, tmp
);
476 if (sval_cmp(min
, tmp
->min
) < 0) { /* new range partially below */
477 if (sval_cmp(max
, tmp
->max
) < 0)
481 new = alloc_range_sval(min
, max
);
482 REPLACE_CURRENT_PTR(tmp
, new);
487 if (sval_cmp(max
, tmp
->max
) <= 0) /* new range already included */
489 if (sval_cmp(min
, tmp
->max
) <= 0) { /* new range partially above */
491 new = alloc_range_sval(min
, max
);
492 REPLACE_CURRENT_PTR(tmp
, new);
496 if (min
.value
- 1 == tmp
->max
.value
) {
497 /* join 2 ranges into a big range */
498 new = alloc_range_sval(tmp
->min
, max
);
499 REPLACE_CURRENT_PTR(tmp
, new);
503 /* the new range is entirely above the existing ranges */
504 } END_FOR_EACH_PTR(tmp
);
507 new = alloc_range_sval(min
, max
);
508 add_ptr_list(list
, new);
511 struct range_list
*clone_range_list(struct range_list
*list
)
513 struct data_range
*tmp
;
514 struct range_list
*ret
= NULL
;
516 FOR_EACH_PTR(list
, tmp
) {
517 add_ptr_list(&ret
, tmp
);
518 } END_FOR_EACH_PTR(tmp
);
522 struct range_list
*clone_permanent(struct range_list
*list
)
524 struct data_range
*tmp
;
525 struct data_range
*new;
526 struct range_list
*ret
= NULL
;
528 FOR_EACH_PTR(list
, tmp
) {
529 new = alloc_range_perm(tmp
->min
, tmp
->max
);
530 add_ptr_list(&ret
, new);
531 } END_FOR_EACH_PTR(tmp
);
535 struct range_list
*range_list_union(struct range_list
*one
, struct range_list
*two
)
537 struct data_range
*tmp
;
538 struct range_list
*ret
= NULL
;
540 FOR_EACH_PTR(one
, tmp
) {
541 add_range(&ret
, tmp
->min
, tmp
->max
);
542 } END_FOR_EACH_PTR(tmp
);
543 FOR_EACH_PTR(two
, tmp
) {
544 add_range(&ret
, tmp
->min
, tmp
->max
);
545 } END_FOR_EACH_PTR(tmp
);
549 struct range_list
*remove_range(struct range_list
*list
, long long min
, long long max
)
551 struct data_range
*tmp
;
552 struct range_list
*ret
= NULL
;
554 FOR_EACH_PTR(list
, tmp
) {
555 if (tmp
->max
< min
) {
556 add_range(&ret
, tmp
->min
, tmp
->max
);
559 if (tmp
->min
> max
) {
560 add_range(&ret
, tmp
->min
, tmp
->max
);
563 if (tmp
->min
>= min
&& tmp
->max
<= max
)
565 if (tmp
->min
>= min
) {
566 add_range(&ret
, max
+ 1, tmp
->max
);
567 } else if (tmp
->max
<= max
) {
568 add_range(&ret
, tmp
->min
, min
- 1);
570 add_range(&ret
, tmp
->min
, min
- 1);
571 add_range(&ret
, max
+ 1, tmp
->max
);
573 } END_FOR_EACH_PTR(tmp
);
577 struct range_list
*invert_range_list(struct range_list
*orig
)
579 struct range_list
*ret
= NULL
;
580 struct data_range
*tmp
;
586 gap_min
= whole_range
.min
;
587 FOR_EACH_PTR(orig
, tmp
) {
588 if (tmp
->min
> gap_min
)
589 add_range(&ret
, gap_min
, tmp
->min
- 1);
590 gap_min
= tmp
->max
+ 1;
591 if (tmp
->max
== whole_range
.max
)
592 gap_min
= whole_range
.max
;
593 } END_FOR_EACH_PTR(tmp
);
595 if (gap_min
!= whole_range
.max
)
596 add_range(&ret
, gap_min
, whole_range
.max
);
602 * if it can be only one and only value return 1, else return 0
604 int estate_get_single_value(struct smatch_state
*state
, long long *val
)
606 struct data_info
*dinfo
;
607 struct data_range
*tmp
;
610 dinfo
= get_dinfo(state
);
611 if (!dinfo
|| dinfo
->type
!= DATA_RANGE
)
614 FOR_EACH_PTR(dinfo
->value_ranges
, tmp
) {
616 if (tmp
->min
!= tmp
->max
)
622 } END_FOR_EACH_PTR(tmp
);
626 int estate_get_single_value_sval(struct smatch_state
*state
, sval_t
*sval
)
628 struct data_info
*dinfo
;
631 dinfo
= get_dinfo(state
);
632 if (!dinfo
|| dinfo
->type
!= DATA_RANGE
)
635 min
= rl_min_sval(dinfo
->value_ranges
);
636 max
= rl_max_sval(dinfo
->value_ranges
);
637 if (sval_cmp(min
, max
) != 0)
643 int ranges_equiv_sval(struct data_range_sval
*one
, struct data_range_sval
*two
)
649 if (sval_cmp(one
->min
, two
->min
) != 0)
651 if (sval_cmp(one
->max
, two
->max
) != 0)
656 int range_lists_equiv(struct range_list
*one
, struct range_list
*two
)
658 struct data_range
*one_range
;
659 struct data_range
*two_range
;
661 PREPARE_PTR_LIST(one
, one_range
);
662 PREPARE_PTR_LIST(two
, two_range
);
664 if (!one_range
&& !two_range
)
666 if (!one_range
|| !two_range
)
668 if (one_range
->min
!= two_range
->min
)
670 if (one_range
->max
!= two_range
->max
)
672 NEXT_PTR_LIST(one_range
);
673 NEXT_PTR_LIST(two_range
);
675 FINISH_PTR_LIST(two_range
);
676 FINISH_PTR_LIST(one_range
);
681 int true_comparison_range(struct data_range
*left
, int comparison
, struct data_range
*right
)
683 struct data_range_sval
*tmp_left
, *tmp_right
;
685 tmp_left
= drange_to_drange_sval(left
);
686 tmp_right
= drange_to_drange_sval(right
);
687 return true_comparison_range_sval(tmp_left
, comparison
, tmp_right
);
690 int true_comparison_range_sval(struct data_range_sval
*left
, int comparison
, struct data_range_sval
*right
)
692 switch (comparison
) {
694 case SPECIAL_UNSIGNED_LT
:
695 if (sval_cmp(left
->min
, right
->max
) < 0)
698 case SPECIAL_UNSIGNED_LTE
:
700 if (sval_cmp(left
->min
, right
->max
) <= 0)
704 if (sval_cmp(left
->max
, right
->min
) < 0)
706 if (sval_cmp(left
->min
, right
->max
) > 0)
709 case SPECIAL_UNSIGNED_GTE
:
711 if (sval_cmp(left
->max
, right
->min
) >= 0)
715 case SPECIAL_UNSIGNED_GT
:
716 if (sval_cmp(left
->max
, right
->min
) > 0)
719 case SPECIAL_NOTEQUAL
:
720 if (sval_cmp(left
->min
, left
->max
) != 0)
722 if (sval_cmp(right
->min
, right
->max
) != 0)
724 if (sval_cmp(left
->min
, right
->min
) != 0)
728 sm_msg("unhandled comparison %d\n", comparison
);
734 int true_comparison_range_lr(int comparison
, struct data_range
*var
, struct data_range
*val
, int left
)
737 return true_comparison_range(var
, comparison
, val
);
739 return true_comparison_range(val
, comparison
, var
);
742 int true_comparison_range_lr_sval(int comparison
, struct data_range_sval
*var
, struct data_range_sval
*val
, int left
)
745 return true_comparison_range_sval(var
, comparison
, val
);
747 return true_comparison_range_sval(val
, comparison
, var
);
750 static int false_comparison_range_sval(struct data_range_sval
*left
, int comparison
, struct data_range_sval
*right
)
752 switch (comparison
) {
754 case SPECIAL_UNSIGNED_LT
:
755 if (sval_cmp(left
->max
, right
->min
) >= 0)
758 case SPECIAL_UNSIGNED_LTE
:
760 if (sval_cmp(left
->max
, right
->min
) > 0)
764 if (sval_cmp(left
->min
, left
->max
) != 0)
766 if (sval_cmp(right
->min
, right
->max
) != 0)
768 if (sval_cmp(left
->min
, right
->min
) != 0)
771 case SPECIAL_UNSIGNED_GTE
:
773 if (sval_cmp(left
->min
, right
->max
) < 0)
777 case SPECIAL_UNSIGNED_GT
:
778 if (sval_cmp(left
->min
, right
->max
) <= 0)
781 case SPECIAL_NOTEQUAL
:
782 if (sval_cmp(left
->max
, right
->min
) < 0)
784 if (sval_cmp(left
->min
, right
->max
) > 0)
788 sm_msg("unhandled comparison %d\n", comparison
);
794 static int false_comparison_range(struct data_range
*left
, int comparison
, struct data_range
*right
)
796 struct data_range_sval
*tmp_left
, *tmp_right
;
798 tmp_left
= drange_to_drange_sval(left
);
799 tmp_right
= drange_to_drange_sval(right
);
800 return false_comparison_range_sval(tmp_left
, comparison
, tmp_right
);
803 int false_comparison_range_lr(int comparison
, struct data_range
*var
, struct data_range
*val
, int left
)
806 return false_comparison_range(var
, comparison
, val
);
808 return false_comparison_range(val
, comparison
, var
);
811 int false_comparison_range_lr_sval(int comparison
, struct data_range_sval
*var
, struct data_range_sval
*val
, int left
)
814 return false_comparison_range_sval(var
, comparison
, val
);
816 return false_comparison_range_sval(val
, comparison
, var
);
819 int possibly_true(struct expression
*left
, int comparison
, struct expression
*right
)
821 struct range_list
*rl_left
, *rl_right
;
822 struct data_range
*tmp_left
, *tmp_right
;
824 if (!get_implied_range_list(left
, &rl_left
))
826 if (!get_implied_range_list(right
, &rl_right
))
829 FOR_EACH_PTR(rl_left
, tmp_left
) {
830 FOR_EACH_PTR(rl_right
, tmp_right
) {
831 if (true_comparison_range(tmp_left
, comparison
, tmp_right
))
833 } END_FOR_EACH_PTR(tmp_right
);
834 } END_FOR_EACH_PTR(tmp_left
);
838 int possibly_false(struct expression
*left
, int comparison
, struct expression
*right
)
840 struct range_list
*rl_left
, *rl_right
;
841 struct data_range
*tmp_left
, *tmp_right
;
843 if (!get_implied_range_list(left
, &rl_left
))
845 if (!get_implied_range_list(right
, &rl_right
))
848 FOR_EACH_PTR(rl_left
, tmp_left
) {
849 FOR_EACH_PTR(rl_right
, tmp_right
) {
850 if (false_comparison_range(tmp_left
, comparison
, tmp_right
))
852 } END_FOR_EACH_PTR(tmp_right
);
853 } END_FOR_EACH_PTR(tmp_left
);
857 int possibly_true_range_lists(struct range_list
*left_ranges
, int comparison
, struct range_list
*right_ranges
)
859 struct data_range
*left_tmp
, *right_tmp
;
861 if (!left_ranges
|| !right_ranges
)
864 FOR_EACH_PTR(left_ranges
, left_tmp
) {
865 FOR_EACH_PTR(right_ranges
, right_tmp
) {
866 if (true_comparison_range(left_tmp
, comparison
, right_tmp
))
868 } END_FOR_EACH_PTR(right_tmp
);
869 } END_FOR_EACH_PTR(left_tmp
);
873 int possibly_true_range_lists_sval(struct range_list_sval
*left_ranges
, int comparison
, struct range_list_sval
*right_ranges
)
875 struct data_range_sval
*left_tmp
, *right_tmp
;
877 if (!left_ranges
|| !right_ranges
)
880 FOR_EACH_PTR(left_ranges
, left_tmp
) {
881 FOR_EACH_PTR(right_ranges
, right_tmp
) {
882 if (true_comparison_range_sval(left_tmp
, comparison
, right_tmp
))
884 } END_FOR_EACH_PTR(right_tmp
);
885 } END_FOR_EACH_PTR(left_tmp
);
889 int possibly_false_range_lists(struct range_list
*left_ranges
, int comparison
, struct range_list
*right_ranges
)
891 struct data_range
*left_tmp
, *right_tmp
;
893 if (!left_ranges
|| !right_ranges
)
896 FOR_EACH_PTR(left_ranges
, left_tmp
) {
897 FOR_EACH_PTR(right_ranges
, right_tmp
) {
898 if (false_comparison_range(left_tmp
, comparison
, right_tmp
))
900 } END_FOR_EACH_PTR(right_tmp
);
901 } END_FOR_EACH_PTR(left_tmp
);
905 int possibly_false_range_lists_sval(struct range_list_sval
*left_ranges
, int comparison
, struct range_list_sval
*right_ranges
)
907 struct data_range_sval
*left_tmp
, *right_tmp
;
909 if (!left_ranges
|| !right_ranges
)
912 FOR_EACH_PTR(left_ranges
, left_tmp
) {
913 FOR_EACH_PTR(right_ranges
, right_tmp
) {
914 if (false_comparison_range_sval(left_tmp
, comparison
, right_tmp
))
916 } END_FOR_EACH_PTR(right_tmp
);
917 } END_FOR_EACH_PTR(left_tmp
);
921 int possibly_true_range_lists_rl(int comparison
, struct range_list
*a
, struct range_list
*b
, int left
)
924 return possibly_true_range_lists(a
, comparison
, b
);
926 return possibly_true_range_lists(b
, comparison
, a
);
929 /* FIXME: the _rl here stands for right left so really it should be _lr */
930 int possibly_true_range_lists_rl_sval(int comparison
, struct range_list_sval
*a
, struct range_list_sval
*b
, int left
)
933 return possibly_true_range_lists_sval(a
, comparison
, b
);
935 return possibly_true_range_lists_sval(b
, comparison
, a
);
938 int possibly_false_range_lists_rl(int comparison
, struct range_list
*a
, struct range_list
*b
, int left
)
941 return possibly_false_range_lists(a
, comparison
, b
);
943 return possibly_false_range_lists(b
, comparison
, a
);
946 int possibly_false_range_lists_rl_sval(int comparison
, struct range_list_sval
*a
, struct range_list_sval
*b
, int left
)
949 return possibly_false_range_lists_sval(a
, comparison
, b
);
951 return possibly_false_range_lists_sval(b
, comparison
, a
);
954 void tack_on(struct range_list
**list
, struct data_range
*drange
)
956 add_ptr_list(list
, drange
);
959 void tack_on_sval(struct range_list_sval
**list
, struct data_range_sval
*drange
)
961 add_ptr_list(list
, drange
);
964 void push_range_list(struct range_list_stack
**rl_stack
, struct range_list
*rl
)
966 add_ptr_list(rl_stack
, rl
);
969 struct range_list
*pop_range_list(struct range_list_stack
**rl_stack
)
971 struct range_list
*rl
;
973 rl
= last_ptr_list((struct ptr_list
*)*rl_stack
);
974 delete_ptr_list_last((struct ptr_list
**)rl_stack
);
978 struct range_list
*top_range_list(struct range_list_stack
*rl_stack
)
980 struct range_list
*rl
;
982 rl
= last_ptr_list((struct ptr_list
*)rl_stack
);
986 void filter_top_range_list(struct range_list_stack
**rl_stack
, long long num
)
988 struct range_list
*rl
;
990 rl
= pop_range_list(rl_stack
);
991 rl
= remove_range(rl
, num
, num
);
992 push_range_list(rl_stack
, rl
);
995 void free_range_list(struct range_list
**rlist
)
997 __free_ptr_list((struct ptr_list
**)rlist
);
1000 static void free_single_dinfo(struct data_info
*dinfo
)
1002 if (dinfo
->type
== DATA_RANGE
)
1003 free_range_list(&dinfo
->value_ranges
);
1006 static void free_dinfos(struct allocation_blob
*blob
)
1008 unsigned int size
= sizeof(struct data_info
);
1009 unsigned int offset
= 0;
1011 while (offset
< blob
->offset
) {
1012 free_single_dinfo((struct data_info
*)(blob
->data
+ offset
));
1017 void free_data_info_allocs(void)
1019 struct allocator_struct
*desc
= &data_info_allocator
;
1020 struct allocation_blob
*blob
= desc
->blobs
;
1023 desc
->allocations
= 0;
1024 desc
->total_bytes
= 0;
1025 desc
->useful_bytes
= 0;
1026 desc
->freelist
= NULL
;
1028 struct allocation_blob
*next
= blob
->next
;
1030 blob_free(blob
, desc
->chunking
);
1033 clear_data_range_alloc();
1036 struct range_list_sval
*range_list_to_sval(struct range_list
*list
)
1038 struct data_range
*tmp
;
1039 struct data_range_sval
*tmp_sval
;
1040 struct range_list_sval
*ret
= NULL
;
1042 FOR_EACH_PTR(list
, tmp
) {
1043 tmp_sval
= drange_to_drange_sval(tmp
);
1044 add_ptr_list(&ret
, tmp_sval
);
1045 } END_FOR_EACH_PTR(tmp
);
1049 struct range_list
*rl_sval_to_rl(struct range_list_sval
*list
)
1051 struct data_range
*tmp
;
1052 struct data_range_sval
*tmp_sval
;
1053 struct range_list
*ret
= NULL
;
1055 FOR_EACH_PTR(list
, tmp_sval
) {
1056 tmp
= drange_sval_to_drange(tmp_sval
);
1057 add_ptr_list(&ret
, tmp
);
1058 } END_FOR_EACH_PTR(tmp_sval
);