Line data Source code
1 : /* Copyright (C) 2012 by Ben Martin */
2 : /*
3 : * Redistribution and use in source and binary forms, with or without
4 : * modification, are permitted provided that the following conditions are met:
5 :
6 : * Redistributions of source code must retain the above copyright notice, this
7 : * list of conditions and the following disclaimer.
8 :
9 : * Redistributions in binary form must reproduce the above copyright notice,
10 : * this list of conditions and the following disclaimer in the documentation
11 : * and/or other materials provided with the distribution.
12 :
13 : * The name of the author may not be used to endorse or promote products
14 : * derived from this software without specific prior written permission.
15 :
16 : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 : * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 : * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 : * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 : * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 : * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 : * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 : * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 : * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 : */
27 : #include <stdlib.h>
28 : #include <stdio.h> /* for NULL */
29 : #include "dlist.h"
30 :
31 0 : void dlist_pushfront( struct dlistnode** list, struct dlistnode* node ) {
32 0 : if( *list ) {
33 0 : node->next = *list;
34 0 : node->next->prev = node;
35 : }
36 0 : *list = node;
37 0 : }
38 :
39 0 : int dlist_size( struct dlistnode** list ) {
40 0 : struct dlistnode* node = *list;
41 0 : int ret = 0;
42 0 : for( ; node; node=node->next ) {
43 0 : ret++;
44 : }
45 0 : return ret;
46 : }
47 :
48 0 : int dlist_isempty( struct dlistnode** list ) {
49 0 : return *list == NULL;
50 : }
51 :
52 0 : void dlist_erase( struct dlistnode** list, struct dlistnode* node ) {
53 0 : if( !node )
54 0 : return;
55 0 : if( *list == node ) {
56 0 : *list = node->next;
57 0 : if( node->next ) {
58 0 : node->next->prev = 0;
59 : }
60 0 : return;
61 : }
62 0 : if( node->prev ) {
63 0 : node->prev->next = node->next;
64 : }
65 0 : if( node->next ) {
66 0 : node->next->prev = node->prev;
67 : }
68 : }
69 :
70 0 : void dlist_foreach( struct dlistnode** list, dlist_foreach_func_type func )
71 : {
72 0 : struct dlistnode* node = *list;
73 0 : while( node ) {
74 0 : struct dlistnode* t = node;
75 0 : node = node->next;
76 0 : func( t );
77 : }
78 0 : }
79 :
80 0 : void dlist_foreach_udata( struct dlistnode** list, dlist_foreach_udata_func_type func, void* udata )
81 : {
82 0 : struct dlistnode* node = *list;
83 0 : while( node ) {
84 0 : struct dlistnode* t = node;
85 0 : node = node->next;
86 0 : func( t, udata );
87 : }
88 0 : }
89 :
90 0 : static struct dlistnode* dlist_last( struct dlistnode* node )
91 : {
92 0 : if( !node )
93 0 : return node;
94 :
95 0 : while( node->next ) {
96 0 : node = node->next;
97 : }
98 0 : return node;
99 : }
100 :
101 0 : struct dlistnode* dlist_popback( struct dlistnode** list ) {
102 0 : struct dlistnode* node = dlist_last(*list);
103 0 : if( node )
104 0 : dlist_erase( list, node );
105 0 : return node;
106 : }
107 :
108 0 : void dlist_foreach_reverse_udata( struct dlistnode** list, dlist_foreach_udata_func_type func, void* udata )
109 : {
110 0 : struct dlistnode* node = dlist_last(*list);
111 0 : while( node ) {
112 0 : struct dlistnode* t = node;
113 0 : node = node->prev;
114 0 : func( t, udata );
115 : }
116 0 : }
117 :
118 0 : void dlist_pushfront_external( struct dlistnode** list, void* ptr )
119 : {
120 0 : struct dlistnodeExternal* n = calloc(1,sizeof(struct dlistnodeExternal));
121 0 : n->ptr = ptr;
122 0 : dlist_pushfront( list, (struct dlistnode*)n );
123 0 : }
124 :
125 0 : static void freenode(struct dlistnode* node )
126 : {
127 0 : free(node);
128 0 : }
129 :
130 0 : void dlist_free_external( struct dlistnode** list )
131 : {
132 0 : if( !list || !(*list) )
133 0 : return;
134 0 : dlist_foreach( list, freenode );
135 : }
136 :
137 0 : void dlist_trim_to_limit( struct dlistnode** list, int limit, dlist_visitor_func_type f )
138 : {
139 0 : int sz = dlist_size( list );
140 0 : while( sz >= limit ) {
141 0 : struct dlistnode* node = dlist_popback( list );
142 0 : f(node);
143 0 : freenode(node);
144 0 : sz = dlist_size( list );
145 : }
146 0 : }
147 :
|