8 int (*compare
)(const void *, const void *);
10 unsigned int alloc
, pos
;
14 void slist_sort(slist
*sl
)
16 /* ignore empty and already sorted lists */
17 if (!sl
|| !sl
->list
|| !sl
->pos
|| sl
->is_sorted
) {
21 qsort(sl
->list
, sl
->pos
, sizeof(void *), sl
->compare
);
26 * The engine of the "sorted list lookup". Arrives at the right
27 * conclusion by bisecting its way around inside the sorted list.
29 int slist_find_pos(slist
*sl
, const void *key
)
32 unsigned int high
, low
= 0;
34 if (!sl
|| !sl
->pos
|| !sl
->list
) {
42 while (high
- low
> 0) {
43 unsigned int mid
= low
+ ((high
- low
) / 2);
45 value
= sl
->compare(&key
, &sl
->list
[mid
]);
49 } else if (value
< 0) {
60 void *slist_find(slist
*sl
, const void *key
)
62 int slot
= slist_find_pos(sl
, key
);
66 return sl
->list
[slot
];
69 static int slist_grow(slist
*sl
, unsigned int hint
)
76 ptr
= realloc(sl
->list
, (sl
->alloc
+ hint
) * sizeof(void *));
84 int slist_push(slist
*sl
, void *item
)
86 if (sl
->pos
>= sl
->alloc
- 1 && slist_grow(sl
, 5) < 0) {
91 * No sorting is required when there's either only
92 * one item in the list, or when the list is added
93 * to in sequential order.
95 sl
->list
[sl
->pos
] = item
;
96 if (sl
->is_sorted
&& sl
->pos
97 && sl
->compare(&sl
->list
[sl
->pos
- 1], &sl
->list
[sl
->pos
]) > 0)
105 void *slist_pop(slist
*sl
)
112 item
= sl
->list
[sl
->pos
];
113 sl
->list
[sl
->pos
] = NULL
;
117 slist
*slist_init(unsigned int hint
, int (*cmp
)(const void *, const void *))
121 sl
= calloc(1, sizeof(*sl
));
125 slist_grow(sl
, hint
);
132 int slist_set_list(slist
*sl
, void **list
, unsigned int items
, int sorted
)
134 if (!sl
|| !list
|| !items
)
146 void slist_release(slist
*sl
)
154 sl
->pos
= sl
->alloc
= 0;
158 void slist_free_items(slist
*sl
)
162 if (!sl
|| !sl
->list
)
164 for (i
= 0; i
< sl
->pos
; i
++)
169 void *slist_destroy(slist
*sl
, int items_too
)
175 slist_free_items(sl
);
183 unsigned int slist_entries(slist
*sl
)
191 void *slist_get_list(slist
*sl
)
199 void slist_walk(slist
*sl
, void *arg
, int (*cb
)(void *, void *))
203 if (!sl
|| !sl
->list
|| !sl
->pos
)
206 for (i
= 0; i
< sl
->pos
; i
++) {
207 cb(arg
, sl
->list
[i
]);