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