1 static char rcsid[] = "$Id: uintlist.c 218147 2019-01-16 21:28:41Z twu $";
2 #ifdef HAVE_CONFIG_H
3 #include <config.h>
4 #endif
5
6 #include "uintlist.h"
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include "mem.h"
11
12 #define T Uintlist_T
13
14 #if !defined(HAVE_INLINE)
15 T
Uintlist_push(T list,unsigned int x)16 Uintlist_push (T list, unsigned int x) {
17 T new = (T) MALLOC(sizeof(*new));
18
19 new->first = x;
20 new->rest = list;
21 return new;
22 }
23
24 T
Uintlist_pop(T list,unsigned int * x)25 Uintlist_pop (T list, unsigned int *x) {
26 T head;
27
28 if (list) {
29 head = list->rest;
30 *x = list->first;
31 FREE(list);
32 return head;
33 } else {
34 return list;
35 }
36 }
37
38 unsigned int
Uintlist_head(T list)39 Uintlist_head (T list) {
40 return list->first;
41 }
42
43 T
Uintlist_next(T list)44 Uintlist_next (T list) {
45 if (list) {
46 return list->rest;
47 } else {
48 return NULL;
49 }
50 }
51
52 void
Uintlist_free(T * list)53 Uintlist_free (T *list) {
54 T prev;
55
56 while ((prev = *list) != NULL) {
57 *list = prev->rest;
58 FREE(prev);
59 }
60
61 return;
62 }
63
64 T
Uintlist_reverse(T list)65 Uintlist_reverse (T list) {
66 T head = NULL, next;
67
68 for ( ; list; list = next) {
69 next = list->rest;
70 list->rest = head;
71 head = list;
72 }
73 return head;
74 }
75
76 int
Uintlist_length(T list)77 Uintlist_length (T list) {
78 int n;
79
80 for (n = 0; list; list = list->rest) {
81 n++;
82 }
83 return n;
84 }
85 #endif
86
87
88 void
Uintlist_head_set(T this,unsigned int x)89 Uintlist_head_set (T this, unsigned int x) {
90 this->first = x;
91 return;
92 }
93
94 T
Uintlist_keep_one(T list,int i)95 Uintlist_keep_one (T list, int i) {
96 T head;
97
98 while (--i >= 0) {
99 /* Pop */
100 head = list->rest;
101 FREE(list);
102 list = head;
103 }
104
105 Uintlist_free(&list->rest);
106 return list;
107 }
108
109 unsigned int
Uintlist_max(T list)110 Uintlist_max (T list) {
111 unsigned int m = 0;
112
113 while (list) {
114 if (list->first > m) {
115 m = list->first;
116 }
117 list = list->rest;
118 }
119
120 return m;
121 }
122
123 unsigned int
Uintlist_min(T list)124 Uintlist_min (T list) {
125 unsigned int m;
126
127 if (list == NULL) {
128 return 0;
129
130 } else {
131 m = list->first;
132 list = list->rest;
133 while (list) {
134 if (list->first < m) {
135 m = list->first;
136 }
137 list = list->rest;
138 }
139
140 return m;
141 }
142 }
143
144 unsigned int *
Uintlist_to_array(int * n,T list)145 Uintlist_to_array (int *n, T list) {
146 unsigned int *array;
147 int i;
148
149 *n = Uintlist_length(list);
150 array = (unsigned int *) CALLOC(*n,sizeof(unsigned int));
151 for (i = 0; i < *n; i++) {
152 array[i] = list->first;
153 list = list->rest;
154 }
155 return array;
156 }
157
158 void
Uintlist_fill_array(unsigned int * array,T list)159 Uintlist_fill_array (unsigned int *array, T list) {
160 int i = 0;
161
162 while (list) {
163 array[i++] = list->first;
164 list = list->rest;
165 }
166
167 return;
168 }
169
170 void
Uintlist_fill_array_and_free(unsigned int * array,T * list)171 Uintlist_fill_array_and_free (unsigned int *array, T *list) {
172 T prev;
173 int i = 0;
174
175 while ((prev = *list) != NULL) {
176 array[i++] = prev->first;
177 *list = prev->rest;
178 FREE(prev);
179 }
180
181 return;
182 }
183
184 unsigned int *
Uintlist_to_array_out(int * n,T list)185 Uintlist_to_array_out (int *n, T list) {
186 unsigned int *array;
187 int i;
188
189 *n = Uintlist_length(list);
190 if (*n == 0) {
191 return NULL;
192 } else {
193 array = (unsigned int *) CALLOC_OUT(*n,sizeof(unsigned int));
194 for (i = 0; i < *n; i++) {
195 array[i] = list->first;
196 list = list->rest;
197 }
198 return array;
199 }
200 }
201
202 T
Uintlist_from_array(unsigned int * array,int n)203 Uintlist_from_array (unsigned int *array, int n) {
204 T list = NULL, p;
205
206 while (--n >= 0) {
207 p = (T) MALLOC(sizeof(*p));
208 p->first = array[n];
209 p->rest = list;
210 list = p;
211 }
212
213 return list;
214 }
215
216 T
Uintlist_copy(T list)217 Uintlist_copy (T list) {
218 T head, *p = &head;
219
220 for ( ; list; list = list->rest) {
221 *p = (T) MALLOC(sizeof(**p));
222 (*p)->first = list->first;
223 p = &(*p)->rest;
224 }
225 *p = NULL;
226 return head;
227 }
228
229 T
Uintlist_append(T list,T tail)230 Uintlist_append (T list, T tail) {
231 T *p = &list;
232
233 while (*p) {
234 p = &(*p)->rest;
235 }
236 *p = tail;
237 return list;
238 }
239
240 unsigned int
Uintlist_last_value(T this)241 Uintlist_last_value (T this) {
242 T last = NULL, r;
243
244 for (r = this; r != NULL; r = r->rest) {
245 last = r;
246 }
247 return last->first;
248 }
249
250 unsigned int
Uintlist_index(T this,int index)251 Uintlist_index (T this, int index) {
252 while (index-- > 0) {
253 this = this->rest;
254 }
255 return this->first;
256 }
257
258
259 bool
Uintlist_find(T this,unsigned int value)260 Uintlist_find (T this, unsigned int value) {
261 T r;
262
263 for (r = this; r != NULL; r = r->rest) {
264 if (r->first == value) {
265 return true;
266 }
267 }
268 return false;
269 }
270
271 char *
Uintlist_to_string(T this)272 Uintlist_to_string (T this) {
273 char *string, Buffer[256];
274 T p;
275 int n, i, strlength;
276
277 if ((n = Uintlist_length(this)) == 0) {
278 string = (char *) CALLOC(1,sizeof(char));
279 string[0] = '\0';
280 } else {
281 strlength = 0;
282 for (i = 0, p = this; i < n-1; i++, p = Uintlist_next(p)) {
283 sprintf(Buffer,"%u,",Uintlist_head(p));
284 strlength += strlen(Buffer);
285 }
286 sprintf(Buffer,"%u",Uintlist_head(p));
287 strlength += strlen(Buffer);
288
289 string = (char *) CALLOC(strlength + 1,sizeof(char));
290 string[0] = '\0';
291 for (i = 0, p = this; i < n-1; i++, p = Uintlist_next(p)) {
292 sprintf(Buffer,"%u,",Uintlist_head(p));
293 strcat(string,Buffer);
294 }
295 sprintf(Buffer,"%u",Uintlist_head(p));
296 strcat(string,Buffer);
297 }
298
299 return string;
300 }
301
302
303 char *
Uintlist_to_string_offset(T this,unsigned int chroffset)304 Uintlist_to_string_offset (T this, unsigned int chroffset) {
305 char *string, Buffer[256];
306 T p;
307 int n, i, strlength;
308
309 if ((n = Uintlist_length(this)) == 0) {
310 string = (char *) CALLOC(1,sizeof(char));
311 string[0] = '\0';
312 } else {
313 strlength = 0;
314 for (i = 0, p = this; i < n-1; i++, p = Uintlist_next(p)) {
315 sprintf(Buffer,"%u,",Uintlist_head(p) - chroffset);
316 strlength += strlen(Buffer);
317 }
318 sprintf(Buffer,"%u",Uintlist_head(p));
319 strlength += strlen(Buffer);
320
321 string = (char *) CALLOC(strlength + 1,sizeof(char));
322 string[0] = '\0';
323 for (i = 0, p = this; i < n-1; i++, p = Uintlist_next(p)) {
324 sprintf(Buffer,"%u,",Uintlist_head(p) - chroffset);
325 strcat(string,Buffer);
326 }
327 sprintf(Buffer,"%u",Uintlist_head(p) - chroffset);
328 strcat(string,Buffer);
329 }
330
331 return string;
332 }
333