Nilorea Library

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

All Data Structures Files Functions Variables Typedefs Macros Groups
n_list.c
Go to the documentation of this file.
1
8 #include "n_list.h"
9
10
11
17 LIST *new_generic_list( int max_items )
18 {
19 LIST *list = NULL ;
20
21 Malloc( list , LIST , 1 );
22 _assert( list , return FALSE );
23
24 if( max_items <= 0 )
25 list -> nb_max_items = 0 ;
26 else
27 list -> nb_max_items = max_items ;
28
29 list -> nb_items = 0 ;
30 list -> start = list -> end = NULL ;
31
32 return list ;
33 } /* new_generic_list */
34
35
36
43 LIST_NODE *new_list_node( void *ptr , void (*destructor)( void *ptr ) )
44 {
45 LIST_NODE *node = NULL ;
46
47 Malloc( node , LIST_NODE , 1 );
48 _assert( node , n_log( LOG_ERR , "Error allocating node for ptr %p" , ptr ); return NULL );
49
50 node -> ptr = ptr ;
51 node -> destroy_func = destructor ;
52 node -> next = node -> prev = NULL ;
53
54 return node ;
55 } /* new_list_node(...) */
56
57
58
65 void *remove_list_node_f( LIST *list , LIST_NODE *node )
66 {
67 void *ptr = NULL ;
68
69 _assert( list , n_log( LOG_ERR , "can't remove from NULL list" ); return NULL );
70 _assert( list->start , n_log( LOG_ERR , "can't remove from NULL list->start" ); return NULL );
71 _assert( list->end , n_log( LOG_ERR , "can't remove from NULL list->end" ); return NULL );
72 _assert( node , n_log( LOG_ERR , "can't remove from NULL node" ); return NULL );
73
74 ptr = node -> ptr ;
75 if( node -> prev && node -> next )
76 {
77 node -> prev -> next = node -> next ;
78 node -> next -> prev = node -> prev ;
79 }
80 else
81 {
82 if( node -> prev == NULL && node -> next )
83 {
84 node -> next -> prev = NULL ;
85 list -> start = node -> next ;
86 }
87 else
88 {
89 if( node -> prev && node -> next == NULL )
90 {
91 node -> prev -> next = NULL ;
92 list -> end = node -> prev ;
93 }
94 else
95 {
96 if( node -> prev == NULL && node -> next == NULL )
97 {
98 /* removing last item */
99 list -> start = list -> end = NULL ;
100 }
101 }
102 }
103 }
104 Free( node );
105 list -> nb_items -- ;
106 return ptr ;
107 } /* remove_list_node_f(...) */
108
109
110
118 int list_push( LIST *list , void *ptr , void (*destructor)( void *ptr ) )
119 {
120 LIST_NODE *node = NULL ;
121
122 _assert( list , n_log( LOG_ERR , "invalid list: NULL" ); return FALSE );
123 _assert( ptr , n_log( LOG_ERR , "invalid ptr: NULL" ); return FALSE );
124
125 if( list -> nb_max_items > 0 && ( list -> nb_items >= list -> nb_max_items ) )
126 {
127 n_log( LOG_ERR , "list is full" );
128 return FALSE ;
129 }
130
131 node = new_list_node( ptr , destructor );
132 _assert( node , n_log( LOG_ERR , "Couldn't allocate new node" ); return FALSE );
133
134 list -> nb_items ++ ;
135
136 if( list -> end )
137 {
138 list -> end -> next = node ;
139 node -> prev = list -> end ;
140 list -> end = node ;
141 }
142 else
143 {
144 list -> start = list -> end = node ;
145 }
146 return TRUE ;
147 } /* list_push( ... ) */
148
149
150
159 int list_push_sorted( LIST *list , void *ptr , int (*comparator)( const void *a , const void *b ) , void (*destructor)( void *ptr ) )
160 {
161 LIST_NODE *nodeptr = NULL ;
162
163 _assert( list , n_log( LOG_ERR , "invalid list: NULL" ); return FALSE );
164 _assert( ptr , n_log( LOG_ERR , "invalid ptr: NULL" ); return FALSE );
165
166 if( list -> nb_max_items > 0 && ( list -> nb_items >= list -> nb_max_items ) )
167 {
168 n_log( LOG_ERR , "list is full" );
169 return FALSE ;
170 }
171
172 if( list -> end )
173 {
174 nodeptr = list -> end ;
175 while( nodeptr && ( comparator( ptr , nodeptr -> ptr ) < 0 ) )
176 nodeptr = nodeptr -> prev ;
177
178 if( !nodeptr )
179 {
180 /* It's the lower ranked element in the sort */
181 list_unshift( list , ptr , destructor );
182 }
183 else
184 {
185 /* we have a match inside the list. let's insert the datas */
186 LIST_NODE *node_next = nodeptr -> next ;
187 LIST_NODE *newnode = new_list_node( ptr , destructor );
188 _assert( newnode , n_log( LOG_ERR , "Couldn't allocate new node" ); return FALSE );
189
190 if( node_next )
191 {
192 link_node( newnode , node_next );
193 }
194 else
195 list -> end = newnode ;
196
197 link_node( nodeptr , newnode );
198 list -> nb_items ++ ;
199 }
200 }
201 else
202 list_push( list , ptr , destructor );
203
204 return TRUE ;
205 } /* list_push_sorted( ... ) */
206
207
208
216 int list_unshift( LIST *list , void *ptr , void (*destructor)( void *ptr ) )
217 {
218 LIST_NODE *node = NULL ;
219
220 _assert( list , n_log( LOG_ERR , "invalid list: NULL" ); return FALSE );
221 _assert( ptr , n_log( LOG_ERR , "invalid ptr: NULL" ); return FALSE );
222
223 if( list -> nb_max_items > 0 && ( list -> nb_items >= list -> nb_max_items ) )
224 {
225 n_log( LOG_ERR , "list is full" );
226 return FALSE ;
227 }
228 node = new_list_node( ptr , destructor );
229 _assert( node , n_log( LOG_ERR , "Couldn't allocate new node" ); return FALSE );
230
231 list -> nb_items ++ ;
232
233 if( list -> start )
234 {
235 link_node( node , list -> start );
236 list -> start = node ;
237 }
238 else
239 {
240 list -> start = list -> end = node ;
241 }
242
243 return TRUE ;
244 } /* list_unshift_f(...) */
245
246
247
256 int list_unshift_sorted( LIST *list , void *ptr , int (*comparator)( void *a , void *b ) , void (*destructor)( void *ptr ) )
257 {
258 LIST_NODE *nodeptr = NULL ;
259
260 _assert( list , n_log( LOG_ERR , "invalid list: NULL" ); return FALSE );
261 _assert( ptr , n_log( LOG_ERR , "invalid ptr: NULL" ); return FALSE );
262
263 if( list -> nb_max_items > 0 && ( list -> nb_items >= list -> nb_max_items ) )
264 {
265 n_log( LOG_ERR , "list is full" );
266 return FALSE ;
267 }
268
269 if( list -> start )
270 {
271 nodeptr = list -> start ;
272 while( nodeptr && ( comparator( ptr , nodeptr -> ptr ) > 0 ) )
273 nodeptr = nodeptr -> next ;
274
275 if( !nodeptr )
276 {
277 /* It's the higher ranked element in the sort */
278 list_push( list , ptr , destructor );
279 }
280 else
281 {
282 /* we have a match inside the list. let's insert the datas */
283 LIST_NODE *node_prev = nodeptr -> prev ;
284 LIST_NODE *newnode = new_list_node( ptr , destructor );
285 _assert( newnode , n_log( LOG_ERR , "Couldn't allocate new node" ); return FALSE );
286
287 if( node_prev )
288 {
289 link_node( node_prev , newnode );
290 }
291 else
292 list -> start = newnode ;
293
294 link_node( newnode , nodeptr );
295 list -> nb_items ++ ;
296 }
297 }
298 else
299 list_unshift( list , ptr , destructor );
300
301 return TRUE ;
302 } /* list_unshift_sorted(...) */
303
304
305
311 void *list_pop_f( LIST *list )
312 {
313 LIST_NODE *nodeptr = NULL ;
314 void *ptr = NULL ;
315
316 _assert( list , n_log( LOG_ERR , "invalid list: NULL" ); return NULL );
317
318 if( list -> nb_items == 0 || list -> end == NULL )
319 return NULL ;
320
321 nodeptr = list -> end ;
322 ptr = nodeptr -> ptr ;
323
324 if( list -> end -> prev )
325 {
326 list -> end = list -> end -> prev ;
327 list -> end -> next = NULL ;
328 }
329
330 list -> nb_items -- ;
331 if( list -> nb_items == 0 )
332 list -> start = list -> end = NULL ;
333
334 Free( nodeptr );
335
336 return ptr ;
337 } /* list_pop_f( ... ) */
338
339
340
346 void *list_shift_f( LIST *list )
347 {
348 LIST_NODE *nodeptr = NULL ;
349 void *ptr = NULL ;
350
351 _assert( list , n_log( LOG_ERR , "invalid list: NULL" ); return NULL );
352
353 if( list -> nb_items == 0 || list -> start == NULL )
354 return NULL ;
355
356 nodeptr = list -> start ;
357 ptr = nodeptr -> ptr ;
358
359 if( list -> start -> next )
360 {
361 list -> start = list -> start -> next ;
362 list -> start -> prev = NULL ;
363 }
364
365 list -> nb_items -- ;
366
367 if( list -> nb_items == 0 )
368 list -> start = list -> end = NULL ;
369
370 Free( nodeptr );
371
372 return ptr ;
373 } /* list_shift_f(...)*/
374
375
376
382 int list_empty( LIST *list )
383 {
384 LIST_NODE *node = NULL , *node_ptr = NULL ;
385
386 _assert( list , n_log( LOG_ERR , "list is NULL" ); return FALSE );
387
388 node = list -> start ;
389 while( node )
390 {
391 node_ptr = node ;
392 node = node -> next ;
393 if( node_ptr -> destroy_func != NULL )
394 {
395 node_ptr -> destroy_func( node_ptr -> ptr );
396 Free( node_ptr );
397 }
398 else
399 {
400 Free( node_ptr );
401 }
402 }
403 list -> start = list -> end = NULL ;
404 list -> nb_items = 0 ;
405 return TRUE ;
406 } /* list_empty( ... ) */
407
408
409
416 int list_empty_with_f( LIST *list , void (*free_fnct)( void *ptr ) )
417 {
418 LIST_NODE *node = NULL , *node_ptr = NULL ;
419
420 if( !list ){ n_log( LOG_ERR , "list is NULL" ); return FALSE ; }
421
422 node = list -> start ;
423 while( node )
424 {
425 node_ptr = node ;
426 node = node -> next ;
427 free_fnct( node_ptr -> ptr );
428 Free( node_ptr );
429 }
430 list -> start = list -> end = NULL ;
431 list -> nb_items = 0 ;
432 return TRUE ;
433 } /* list_empty_with_f */
434
435
436
442 int list_destroy( LIST **list )
443 {
444 _assert( (*list) , n_log( LOG_ERR , "list already destroyed" ); return FALSE );
445 list_empty( (*list) );
446 Free( (*list ) );
447 return TRUE ;
448 } /* free_list( ... ) */