1 /****************************************************************************
2 Copyright (C) 1987-2015 by Jeffery P. Hansen
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 ****************************************************************************/
18 #include <stdlib.h>
19 #include "misc.h"
20 #include "list.h"
21
new_List()22 List *new_List()
23 {
24 List *L = MALLOC(List);
25
26 List_init(L);
27
28 return L;
29 }
30
delete_List(List * L)31 void delete_List(List *L)
32 {
33 List_uninit(L);
34 free(L);
35 }
36
37
copy_List(List * L)38 List *copy_List(List *L)
39 {
40 List *CL = MALLOC(List);
41 ListElem *E;
42
43 List_init(CL);
44 for (E = List_first(L);E;E = List_next(L,E)) {
45 List_addToTail(CL, ListElem_obj(E));
46 }
47
48 return CL;
49 }
50
List_init(List * L)51 void List_init(List *L)
52 {
53 L->num = 0;
54 L->first = L->last = 0;
55 }
56
List_flush(List * L)57 void List_flush(List *L)
58 {
59 ListElem *E,*N;
60
61 for (E = List_first(L);E;E = N) {
62 N = List_next(L,E);
63 free(E);
64 }
65 List_init(L);
66 }
67
List_addToHead(List * L,void * p)68 void List_addToHead(List *L,void *p)
69 {
70 ListElem *E = MALLOC(ListElem);
71
72 if (L->first) L->first->prev = E;
73 E->obj = p;
74 E->next = L->first;
75 E->prev = 0;
76 L->first = E;
77 if (!L->last) L->last = E;
78 L->num++;
79 }
80
List_addToTail(List * L,void * p)81 void List_addToTail(List *L,void *p)
82 {
83 ListElem *E = MALLOC(ListElem);
84
85 if (L->last) L->last->next = E;
86 E->obj = p;
87 E->prev = L->last;
88 E->next = 0;
89 L->last = E;
90 if (!L->first) L->first = E;
91 L->num++;
92 }
93
List_popHead(List * L)94 void *List_popHead(List *L)
95 {
96 ListElem *E = L->first;
97 void *p;
98
99 if (!E) return 0;
100 p = E->obj;
101 L->first = E->next;
102 if (L->first)
103 L->first->prev = 0;
104 else
105 L->last = 0;
106 free(E);
107 L->num--;
108
109 return p;
110 }
111
List_popTail(List * L)112 void *List_popTail(List *L)
113 {
114 ListElem *E = L->last;
115 void *p;
116
117 if (!E) return 0;
118 p = E->obj;
119 L->last = E->prev;
120 if (L->last)
121 L->last->next = 0;
122 else
123 L->first = 0;
124 free(E);
125 L->num--;
126
127 return p;
128 }
129
List_remove(List * L,ListElem * E)130 void *List_remove(List *L,ListElem *E)
131 {
132 if (E->prev)
133 E->prev->next = E->next;
134 else {
135 L->first = E->next;
136 L->first->prev = 0;
137 }
138
139 if (E->next)
140 E->next->prev = E->prev;
141 else {
142 L->last = E->prev;
143 L->last->next = 0;
144 }
145 L->num--;
146 free(E);
147 return L;
148 }
149
List_append(List * L,List * A)150 void List_append(List *L,List *A)
151 {
152 ListElem *E;
153
154 for (E = List_first(A);E;E = List_next(A,E)) {
155 List_addToTail(L,ListElem_obj(E));
156 }
157 }
158
159 /*
160 get the nth element in list
161 */
List_nth(List * L,int n)162 void *List_nth(List *L,int n)
163 {
164 ListElem *E;
165
166 for (E = List_first(L);E && n-- > 0;E = List_next(L,E));
167
168 return E ? ListElem_obj(E) : 0;
169 }
170
List_find(List * L,const void * obj,elemcmp_f * cmpfunc)171 void *List_find(List *L,const void *obj,elemcmp_f *cmpfunc)
172 {
173 ListElem *le;
174
175 for (le = List_first(L);le;le = List_next(L,le)) {
176 void *list_obj = ListElem_obj(le);
177
178 if ((*cmpfunc)(&list_obj,&obj) == 0)
179 return list_obj;
180 }
181
182 return 0;
183 }
184
List_sort(List * L,elemcmp_f * cmpfunc)185 void List_sort(List *L,elemcmp_f *cmpfunc)
186 {
187 if (List_numElems(L) > 1) {
188 /* void **a = (void**) malloc(sizeof(void*)*List_numElems(L));*/
189 void **a = (void**)calloc(List_numElems(L), sizeof (void*));
190 ListElem *le;
191 int i;
192
193 i = 0;
194 for (le = List_first(L);le;le = List_next(L,le))
195 a[i++] = ListElem_obj(le);
196
197 qsort(a,List_numElems(L),sizeof(void*),cmpfunc);
198
199 i = 0;
200 for (le = List_first(L);le;le = List_next(L,le))
201 le->obj = a[i++];
202
203 free(a);
204 }
205 }
206
207