1 : #define _GNU_SOURCE 1
2 :
3 : #include "bag.h"
4 :
5 : /* need to use vlg etc. */
6 : #define EX_UTILS_NO_FUNCS 1
7 : #include "ex_utils.h"
8 :
9 : #include "glibc-strverscmp.h"
10 :
11 : void bag_del_all(Bag *bag)
12 38 : {
13 98 : while (bag->num--)
14 : {
15 22 : bag->free_key_func((void *)bag->data[bag->num].key);
16 22 : bag->free_val_func(bag->data[bag->num].val);
17 : }
18 38 : bag->num = 0;
19 38 : }
20 :
21 : Bag *bag_make(size_t sz,
22 : void (*free_key_func)(void *), void (*free_val_func)(void *))
23 8 : {
24 8 : Bag *bag = malloc(sizeof(Bag) + (sizeof(Bag_obj) * sz));
25 :
26 8 : if (!bag)
27 0 : return (NULL);
28 :
29 8 : bag->num = 0;
30 8 : bag->sz = sz;
31 8 : bag->free_key_func = free_key_func;
32 8 : bag->free_val_func = free_val_func;
33 :
34 8 : bag->can_resize = FALSE;
35 :
36 8 : return (bag);
37 : }
38 :
39 : void bag_free(Bag *bag)
40 96 : {
41 96 : if (!bag)
42 80 : return;
43 :
44 16 : bag_del_all(bag);
45 :
46 16 : free(bag);
47 : }
48 :
49 : Bag *bag_add_obj(Bag *bag, const char *key, void *val)
50 22 : {
51 11 : ASSERT(bag);
52 :
53 11 : ASSERT(bag->num <= bag->sz);
54 :
55 22 : if ((bag->num >= bag->sz))
56 : {
57 0 : Bag *tmp = NULL;
58 0 : size_t sz = bag->sz;
59 :
60 0 : if (!bag->can_resize)
61 0 : return (NULL);
62 :
63 0 : sz <<= 1;
64 0 : if (!(tmp = realloc(bag, sizeof(Bag) + (sizeof(Bag_obj) * sz))))
65 0 : return (NULL);
66 :
67 0 : bag = tmp;
68 0 : bag->sz = sz;
69 : }
70 :
71 22 : bag->data[bag->num].key = key;
72 22 : bag->data[bag->num].val = val;
73 22 : ++bag->num;
74 :
75 22 : return (bag);
76 : }
77 :
78 : Bag *bag_add_cstr(Bag *bag, const char *key, char *val)
79 0 : {
80 0 : return (bag_add_obj(bag, key, val));
81 : }
82 :
83 : void bag_sort(Bag *bag, int (*cmp)(const void *, const void *))
84 0 : {
85 0 : qsort(bag->data, bag->num, sizeof(Bag_obj), cmp);
86 0 : }
87 :
88 : int bag_cb_sort_key_cmp(const void *passed_one, const void *passed_two)
89 0 : {
90 0 : const Bag_obj *const one = passed_one;
91 0 : const Bag_obj *const two = passed_two;
92 :
93 0 : return (strcmp(one->key, two->key));
94 : }
95 :
96 : int bag_cb_sort_key_case(const void *passed_one, const void *passed_two)
97 0 : {
98 0 : const Bag_obj *const one = passed_one;
99 0 : const Bag_obj *const two = passed_two;
100 :
101 0 : return (strcasecmp(one->key, two->key));
102 : }
103 :
104 : int bag_cb_sort_key_vers(const void *passed_one, const void *passed_two)
105 0 : {
106 0 : const Bag_obj *const one = passed_one;
107 0 : const Bag_obj *const two = passed_two;
108 :
109 0 : return (strverscmp(one->key, two->key));
110 : }
111 :
112 : int bag_cb_sort_key_coll(const void *passed_one, const void *passed_two)
113 0 : {
114 0 : const Bag_obj *const one = passed_one;
115 0 : const Bag_obj *const two = passed_two;
116 :
117 0 : return (strcoll(one->key, two->key));
118 : }
119 :
120 : const Bag_obj *bag_iter_nxt(Bag_iter *iter)
121 134 : {
122 68 : ASSERT(iter);
123 :
124 134 : if (iter->num >= iter->bag->num)
125 76 : return (NULL);
126 :
127 58 : return (iter->bag->data + iter->num++);
128 : }
129 :
130 : const Bag_obj *bag_iter_beg(Bag *bag, Bag_iter *iter)
131 98 : {
132 50 : ASSERT(bag && iter);
133 :
134 98 : iter->bag = bag;
135 98 : iter->num = 0;
136 :
137 98 : return (bag_iter_nxt(iter));
138 : }
139 :
140 : const Bag_obj *bag_srch_eq(Bag *bag,
141 : int (*cmp_func)(const Bag_obj *, const void *),
142 : const void *val)
143 22 : {
144 : Bag_iter iter[1];
145 22 : const Bag_obj *obj = bag_iter_beg(bag, iter);
146 :
147 44 : while (obj)
148 : {
149 0 : if ((*cmp_func)(obj, val))
150 0 : return (obj);
151 :
152 0 : obj = bag_iter_nxt(iter);
153 : }
154 :
155 22 : return (NULL);
156 : }
157 :
158 : int bag_cb_srch_eq_key_ptr(const Bag_obj *obj, const void *val)
159 0 : {
160 0 : if (obj->key == val)
161 0 : return (TRUE);
162 :
163 0 : return (FALSE);
164 : }
165 :
166 : int bag_cb_srch_eq_val_ptr(const Bag_obj *obj, const void *val)
167 0 : {
168 0 : if (obj->val == val)
169 0 : return (TRUE);
170 :
171 0 : return (FALSE);
172 : }
173 :
174 : void bag_cb_free_nothing(void *COMPILE_ATTR_UNUSED(val))
175 22 : {
176 22 : }
177 :
178 : void bag_cb_free_ref(void *val)
179 0 : {
180 0 : vstr_ref_del(val);
181 0 : }
182 :
183 : void bag_cb_free_malloc(void *val)
184 0 : {
185 0 : free(val);
186 0 : }
187 :
|