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