/[radius]/radius/lib/list.c
ViewVC logotype

Diff of /radius/lib/list.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.3 by gray, Tue Apr 29 13:56:56 2003 UTC revision 1.4 by gray, Wed Apr 30 20:11:38 2003 UTC
# Line 22  Line 22 
22  #include <stdlib.h>  #include <stdlib.h>
23  #include <mem.h>  #include <mem.h>
24  #include <list.h>  #include <list.h>
25    #include <assert.h>
26    
27  struct list_entry {  struct list_entry {
28          struct list_entry *next;          struct list_entry *next;
# Line 30  struct list_entry { Line 31  struct list_entry {
31    
32  struct list {  struct list {
33          size_t count;          size_t count;
34          struct list_entry *head, *tail, *cur, *next;          struct list_entry *head, *tail;
35            struct iterator *itr;
36    };
37    
38    struct iterator {
39            struct iterator *next;
40            LIST *list;
41            struct list_entry *cur;
42  };  };
43    
44  struct list *  struct list *
45  list_create()  list_create()
46  {  {
47          struct list *p = emalloc(sizeof(*p));          struct list *p = emalloc(sizeof(*p));
48          p->head = p->tail = p->cur = p->next = NULL;          p->head = p->tail = NULL;
49            p->itr = NULL;
50          return p;          return p;
51  }  }
52    
# Line 61  list_destroy(struct list **plist, list_i Line 70  list_destroy(struct list **plist, list_i
70          *plist = NULL;          *plist = NULL;
71  }  }
72    
73  void  void *
74  list_iterate(struct list *list, list_iterator_t itr, void *data)  iterator_current(ITERATOR *ip)
75  {  {
76          if (!list)          if (!ip)
77                  return;                  return NULL;
78          for (list->cur = list->head; list->cur; list->cur = list->next) {          return ip->cur ? ip->cur->data : NULL;
                 list->next = list->cur->next;  
                 if (itr(list->cur->data, data))  
                         break;  
         }  
79  }  }
80    
81  void *  ITERATOR *
82  list_current(struct list *list)  iterator_create(LIST *list)
83  {  {
84            ITERATOR *itr;
85    
86          if (!list)          if (!list)
87                  return NULL;                  return NULL;
88          return list->cur ? list->cur->data : NULL;          itr = emalloc(sizeof(*itr));
89            itr->list = list;
90            itr->cur = NULL;
91            itr->next = list->itr;
92            list->itr = itr;
93            return itr;
94  }  }
95    
96    void
97    iterator_destroy(ITERATOR **ip)
98    {
99            ITERATOR *itr, *prev;
100    
101            if (!ip || !*ip)
102                    return;
103            for (itr = (*ip)->list->itr, prev = NULL;
104                 itr;
105                 prev = itr, itr = itr->next)
106                    if (*ip == itr)
107                            break;
108            if (itr) {
109                    if (prev)
110                            prev->next = itr->next;
111                    else
112                            itr->list->itr = itr->next;
113                    efree(itr);
114                    *ip = NULL;
115            }
116                    
117    }
118                    
119  void *  void *
120  list_first(struct list *list)  iterator_first(ITERATOR *ip)
121  {  {
122          if (!list)          if (!ip)
123                  return NULL;                  return NULL;
124          list->cur = list->head;          ip->cur = ip->list->head;
125          if (list->cur)          return iterator_current(ip);
                 list->next = list->cur->next;  
         return list_current(list);  
126  }  }
127    
128  void *  void *
129  list_next(struct list *list)  iterator_next(ITERATOR *ip)
130  {  {
131          if (!list || !list->next)          if (!ip || !ip->cur)
132                  return NULL;                  return NULL;
133          list->cur = list->next;          ip->cur = ip->cur->next;
134          if (list->cur)          return iterator_current(ip);
                 list->next = list->cur->next;  
         return list_current(list);  
135  }        }      
136    
137    static void
138    _iterator_advance(ITERATOR *ip, struct list_entry *e)
139    {
140            for (; ip; ip = ip->next)
141                    if (ip->cur == e)
142                            ip->cur = e->next;
143    }
144    
145  void *  void *
146  list_item(struct list *list, size_t n)  list_item(struct list *list, size_t n)
147  {  {
# Line 127  list_append(struct list *list, void *dat Line 166  list_append(struct list *list, void *dat
166  {  {
167          struct list_entry *ep;          struct list_entry *ep;
168    
169            assert(list!=NULL);
170          if (!list)          if (!list)
171                  return;                  return;
172          ep = emalloc(sizeof(*ep));          ep = emalloc(sizeof(*ep));
# Line 163  cmp_ptr(const void *a, const void *b) Line 203  cmp_ptr(const void *a, const void *b)
203  }  }
204    
205  void *  void *
206  list_locate(struct list *list, void *data, list_comp_t cmp)  list_remove(struct list *list, void *data, list_comp_t cmp)
207  {  {
208            struct list_entry *p, *prev;
209    
210          if (!list)          if (!list)
211                  return NULL;                  return NULL;
212            if (!list->head)
213                    return NULL;
214          if (!cmp)          if (!cmp)
215                  cmp = cmp_ptr;                  cmp = cmp_ptr;
216          for (list->cur = list->head; list->cur; list->cur = list->cur->next)          for (p = list->head, prev = NULL; p; prev = p, p = p->next)
217                  if (cmp(list->cur->data, data) == 0)                  if (cmp(p->data, data) == 0)
218                          break;                          break;
219          return list_current(list);          _iterator_advance(list->itr, p);
220  }          if (p == list->head) {
           
 static struct list_entry *  
 _list_remove_item(struct list *list, struct list_entry *item)  
 {  
         struct list_entry *p = NULL;  
         if (item == list->head) {  
221                  list->head = list->head->next;                  list->head = list->head->next;
222                  if (!list->head)                  if (!list->head)
223                          list->tail = NULL;                          list->tail = NULL;
224          } else {          } else
225                  for (p = list->head; p && p->next != item; p = p->next)                  prev->next = p->next;
226                          ;  
227                  p->next = item->next;          if (p == list->tail)
228                  if (item == list->tail)                  list->tail = prev;
                         list->tail = p;  
         }  
229    
230          efree(item);          efree(p);
231          list->count--;          list->count--;
232          return p;          
233            return data;
234  }  }
235    
236  void *  void
237  list_remove_current(struct list *list)  list_iterate(struct list *list, list_iterator_t func, void *data)
238  {  {
239          struct list_entry *cur;          ITERATOR *itr;
240          void *data;          void *p;
241                    
242          if (!list || !list->cur)          if (!list)
243                  return NULL;                  return;
244            itr = iterator_create(list);
245          cur = list->cur;          if (!itr)
246          data = cur->data;                  return;
247          if (list->cur == list->head) {          for (p = iterator_first(itr); p; p = iterator_next(itr)) {
248                  list->cur = cur->next;                  if (func(p, data))
249                  _list_remove_item(list, cur);                          break;
250          } else          }
251                  list->cur = _list_remove_item(list, cur);          iterator_destroy(&itr);
         if (list->cur)  
                 list->next = list->cur->next;  
         else  
                 list->next = NULL;  
         return data;  
252  }  }
253            
254  void *  void *
255  list_remove(struct list *list, void *data, list_comp_t cmp)  list_locate(struct list *list, void *data, list_comp_t cmp)
256  {  {
257          struct list_entry *p;          struct list_entry *cur;
   
258          if (!list)          if (!list)
259                  return NULL;                  return NULL;
         if (!list->head)  
                 return NULL;  
260          if (!cmp)          if (!cmp)
261                  cmp = cmp_ptr;                  cmp = cmp_ptr;
262          for (p = list->head; p; p = p->next)          for (cur = list->head; cur; cur = cur->next)
263                  if (cmp(p->data, data) == 0)                  if (cmp(cur->data, data) == 0)
264                          break;                          break;
265          if (p == list->cur)          return cur ? cur->data : NULL;
                 return list_remove_current(list);  
         else if (p)  
                 _list_remove_item(list, p);  
         if (list->cur)  
                 list->next = list->cur->next;  
         else  
                 list->next = NULL;  
         return data;  
266  }  }
267            
 void  
 list_append_list(struct list *a, struct list *b)  
 {  
         if (a->tail) {  
                 a->tail->next = b->head;  
                 a->tail = b->tail;  
         } else {  
                 a->head = b->head;  
                 a->tail = b->tail;  
         }  
         a->count += b->count;  
   
         b->head = b->tail = b->cur = NULL;  
 }  
   
   
268    

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.4

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26