1 /*
2  *     gtkatlantic - the gtk+ monopd client, enjoy network monopoly games
3  *
4  *
5  *  Copyright © 2002-2015 Sylvain Rochet
6  *
7  *  gtkatlantic is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; see the file COPYING. If not, see
19  *  <http://www.gnu.org/licenses/>.
20  */
21 
22 #include "config.h"
23 
24 #include <glib.h>
25 
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <unistd.h>
29 #include <string.h>
30 
31 #include "eng_list.h"
32 
33 
eng_list_new()34 eng_list *eng_list_new()  {
35 
36 	eng_list *l;
37 	l = g_malloc0( sizeof(eng_list) );
38 	return l;
39 }
40 
41 
eng_list_destroy(eng_list * l)42 eng_list *eng_list_destroy(eng_list *l) {
43 
44 	if(!l)  return NULL;
45 	eng_list_clean(l);
46 	g_free(l);
47 	return NULL;
48 }
49 
50 
eng_list_element_new(eng_list * l,void * d)51 eng_list_e *eng_list_element_new(eng_list *l, void *d)  {
52 
53 	eng_list_e *le;
54 
55 	if(!l)  return NULL;
56 	le = g_malloc0( sizeof(eng_list_e) );
57 	if(!l->length)  l->first = l->last = le;
58 
59 	le->list = l;
60 	le->data = d;
61 	l->length++;
62 
63 	return le;
64 }
65 
66 
eng_list_append(eng_list * l,void * d)67 eng_list_e *eng_list_append(eng_list *l, void *d)  {
68 
69 	eng_list_e *le;
70 
71 	le = eng_list_element_new(l, d);
72 
73 	if(l->last != le)  {
74 		le->prev = l->last;
75 		le->prev->next = le;
76 		l->last = le;
77 	}
78 	else  le->prev = NULL;
79 	le->next = NULL;
80 
81 	return le;
82 }
83 
84 
eng_list_prepend(eng_list * l,void * d)85 eng_list_e *eng_list_prepend(eng_list *l, void *d)  {
86 
87 	eng_list_e *le;
88 
89 	le = eng_list_element_new(l, d);
90 
91 	if(l->first != le)  {
92 		le->next = l->first;
93 		le->next->prev = le;
94 		l->first = le;
95 	}
96 	else  le->next = NULL;
97 	le->prev = NULL;
98 
99 	return le;
100 }
101 
102 
eng_list_remove_fast(eng_list_e * le)103 void eng_list_remove_fast(eng_list_e *le)  {
104 
105 	eng_list *l;
106 
107 	if(!le)  return;
108 	l = le->list;
109 	l->length--;
110 
111 	if(!le->prev) {
112 		if(le->next)  {  // prev = 0, next = 1
113 			l->first = le->next;
114 			le->next->prev = NULL;
115 		}
116 		else /* if(!le->next) */ {  // prev = 0, next = 0
117 			l->first = l->last = NULL;
118 		}
119 	}
120 	else /* if(le->prev) */ {  // prev = 1, next = 0
121 		if(!le->next) {
122 			l->last = le->prev;
123 			le->prev->next = NULL;
124 		}
125 		else /* if(le->next) */ {  // prev = 1, next = 1
126 			le->next->prev = le->prev;
127 			le->prev->next = le->next;
128 		}
129 	}
130 
131 	g_free(le);
132 }
133 
134 
eng_list_remove(eng_list * l,void * d)135 void eng_list_remove(eng_list *l, void *d)  {
136 
137 	eng_list_e *le;
138 	if(!l)  return;
139 
140 	if( (le = eng_list_find(l, d)) )
141 		eng_list_remove_fast(le);
142 }
143 
144 
eng_list_first(eng_list * l)145 eng_list_e *eng_list_first(eng_list *l)  {
146 
147 	if(!l)  return NULL;
148 	return(l->first);
149 }
150 
151 
eng_list_last(eng_list * l)152 eng_list_e *eng_list_last(eng_list *l)  {
153 
154 	if(!l)  return NULL;
155 	return(l->last);
156 }
157 
158 
eng_list_previous(eng_list_e * le)159 eng_list_e *eng_list_previous(eng_list_e *le)  {
160 
161 	if(!le)  return NULL;
162 	return(le->prev);
163 }
164 
165 
eng_list_next(eng_list_e * le)166 eng_list_e *eng_list_next(eng_list_e *le)  {
167 
168 	if(!le)  return NULL;
169 	return(le->next);
170 }
171 
172 
eng_list_clean(eng_list * l)173 void eng_list_clean(eng_list *l)  {
174 
175 	if(!l)  return;
176 	while(l->first)  eng_list_remove_fast(l->first);
177 }
178 
179 
eng_list_length(eng_list * l)180 guint32 eng_list_length(eng_list *l)  {
181 
182 	if(!l)  return 0;
183 	return(l->length);
184 }
185 
186 
eng_list_find(eng_list * l,void * d)187 eng_list_e *eng_list_find(eng_list *l, void *d)  {
188 
189 	eng_list_e *le;
190 	if(!l)  return NULL;
191 	for(le = l->first ; le ; le = le->next)
192 		if(le->data == d)  {
193 			return le;
194 		}
195 	return NULL;
196 }
197 
198 
eng_list_libevlist_to_glist(eng_list * l)199 GList *eng_list_libevlist_to_glist(eng_list *l)  {
200 
201 	eng_list_e *le;
202 	GList *gl = NULL;
203 
204 	for(le = eng_list_first(l); le; le = le->next)
205 		gl = g_list_append(gl, le->data);
206 
207 	return g_list_first(gl);
208 }
209 
210 
eng_list_glist_to_libevlist(GList * gl)211 eng_list *eng_list_glist_to_libevlist(GList *gl)  {
212 
213 	eng_list *l;
214 	GList *gle;
215 
216 	l = eng_list_new();
217 
218 	for(gle = g_list_first(gl); gle; gle = gle->next)
219 		eng_list_append(l, gle->data);
220 
221 	return l;
222 }
223