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