/[anubis]/anubis/src/list.c
ViewVC logotype

Diff of /anubis/src/list.c

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

revision 1.3 by gray, Thu Mar 6 18:40:41 2003 UTC revision 1.4 by gray, Sat May 10 08:56:44 2003 UTC
# Line 31  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            int advanced;
43  };  };
44    
45  struct list *  struct list *
46  list_create()  list_create()
47  {  {
48          struct list *p = xmalloc(sizeof(*p));          struct list *p = xmalloc(sizeof(*p));
49          p->head = p->tail = p->cur = p->next = NULL;          p->head = p->tail = NULL;
50            p->itr = NULL;
51          return p;          return p;
52  }  }
53    
# Line 55  list_destroy(struct list **plist, list_i Line 64  list_destroy(struct list **plist, list_i
64                  struct list_entry *next = p->next;                  struct list_entry *next = p->next;
65                  if (user_free)                  if (user_free)
66                          user_free(p->data, data);                          user_free(p->data, data);
67                  free(p);                  xfree(p);
68                  p = next;                  p = next;
69          }          }
70          free(*plist);          xfree(*plist);
71          *plist = NULL;          *plist = NULL;
72  }  }
73    
74  void  void *
75  list_iterate(struct list *list, list_iterator_t itr, void *data)  iterator_current(ITERATOR *ip)
76  {  {
77          if (!list)          if (!ip)
78                  return;                  return NULL;
79          for (list->cur = list->head; list->cur; list->cur = list->next) {          return ip->cur ? ip->cur->data : NULL;
                 list->next = list->cur->next;  
                 itr(list->cur->data, data);  
         }  
80  }  }
81    
82  void *  ITERATOR *
83  list_current(struct list *list)  iterator_create(LIST *list)
84  {  {
85            ITERATOR *itr;
86    
87          if (!list)          if (!list)
88                  return NULL;                  return NULL;
89          return list->cur ? list->cur->data : NULL;          itr = xmalloc(sizeof(*itr));
90            itr->list = list;
91            itr->cur = NULL;
92            itr->next = list->itr;
93            itr->advanced = 0;
94            list->itr = itr;
95            return itr;
96  }  }
97    
98    void
99    iterator_destroy(ITERATOR **ip)
100    {
101            ITERATOR *itr, *prev;
102    
103            if (!ip || !*ip)
104                    return;
105            for (itr = (*ip)->list->itr, prev = NULL;
106                 itr;
107                 prev = itr, itr = itr->next)
108                    if (*ip == itr)
109                            break;
110            if (itr) {
111                    if (prev)
112                            prev->next = itr->next;
113                    else
114                            itr->list->itr = itr->next;
115                    xfree(itr);
116                    *ip = NULL;
117            }
118                    
119    }
120                    
121  void *  void *
122  list_first(struct list *list)  iterator_first(ITERATOR *ip)
123  {  {
124          if (!list)          if (!ip)
125                  return NULL;                  return NULL;
126          list->cur = list->head;          ip->cur = ip->list->head;
127          if (list->cur)          ip->advanced = 0;
128                  list->next = list->cur->next;          return iterator_current(ip);
         return list_current(list);  
129  }  }
130    
131  void *  void *
132  list_next(struct list *list)  iterator_next(ITERATOR *ip)
133  {  {
134          if (!list || !list->next)          if (!ip || !ip->cur)
135                  return NULL;                  return NULL;
136          list->cur = list->next;          if (!ip->advanced)
137          if (list->cur)                  ip->cur = ip->cur->next;
138                  list->next = list->cur->next;          ip->advanced = 0;
139          return list_current(list);          return iterator_current(ip);
140  }        }      
141    
142    static void
143    _iterator_advance(ITERATOR *ip, struct list_entry *e)
144    {
145            for (; ip; ip = ip->next) {
146                    if (ip->cur == e) {
147                            ip->cur = e->next;
148                            ip->advanced++;
149                    }
150            }
151    }
152    
153  void *  void *
154  list_item(struct list *list, size_t n)  list_item(struct list *list, size_t n)
155  {  {
# Line 159  list_prepend(struct list *list, void *da Line 206  list_prepend(struct list *list, void *da
206  static int  static int
207  cmp_ptr(void *a, void *b)  cmp_ptr(void *a, void *b)
208  {  {
209          return a == b;          return a != b;
210  }  }
211    
212  void *  void *
213  list_locate(struct list *list, void *data, list_comp_t cmp)  list_remove(struct list *list, void *data, list_comp_t cmp)
214  {  {
215            struct list_entry *p, *prev;
216    
217          if (!list)          if (!list)
218                  return NULL;                  return NULL;
219            if (!list->head)
220                    return NULL;
221          if (!cmp)          if (!cmp)
222                  cmp = cmp_ptr;                  cmp = cmp_ptr;
223          for (list->cur = list->head; list->cur; list->cur = list->cur->next)          for (p = list->head, prev = NULL; p; prev = p, p = p->next)
224                  if (cmp(list->cur->data, data) == 0)                  if (cmp(p->data, data) == 0)
225                          break;                          break;
226          return list_current(list);  
227  }          if (!p)
228                            return 0;
229  static struct list_entry *          _iterator_advance(list->itr, p);
230  _list_remove_item(struct list *list, struct list_entry *item)          if (p == list->head) {
 {  
         struct list_entry *p = NULL;  
         if (item == list->head) {  
231                  list->head = list->head->next;                  list->head = list->head->next;
232                  if (!list->head)                  if (!list->head)
233                          list->tail = NULL;                          list->tail = NULL;
234          } else {          } else
235                  for (p = list->head; p && p->next != item; p = p->next)                  prev->next = p->next;
236                          ;          
237                  p->next = item->next;          if (p == list->tail)
238                  if (item == list->tail)                  list->tail = prev;
239                          list->tail = p;          
240          }          xfree(p);
   
         free(item);  
241          list->count--;          list->count--;
242          return p;          
243            return data;
244  }  }
245    
246  void *  void
247  list_remove_current(struct list *list)  list_iterate(struct list *list, list_iterator_t func, void *data)
248  {  {
249          struct list_entry *cur;          ITERATOR *itr;
250          void *data;          void *p;
251                    
252          if (!list || !list->cur)          if (!list)
253                  return NULL;                  return;
254            itr = iterator_create(list);
255          cur = list->cur;          if (!itr)
256          data = cur->data;                  return;
257          if (list->cur == list->head) {          for (p = iterator_first(itr); p; p = iterator_next(itr)) {
258                  list->cur = cur->next;                  if (func(p, data))
259                  _list_remove_item(list, cur);                          break;
260          } else          }
261                  list->cur = _list_remove_item(list, cur);          iterator_destroy(&itr);
         return data;  
262  }  }
263            
264  void *  void *
265  list_remove(struct list *list, void *data, list_comp_t cmp)  list_locate(struct list *list, void *data, list_comp_t cmp)
266  {  {
267          struct list_entry *p;          struct list_entry *cur;
   
268          if (!list)          if (!list)
269                  return NULL;                  return NULL;
         if (!list->head)  
                 return NULL;  
270          if (!cmp)          if (!cmp)
271                  cmp = cmp_ptr;                  cmp = cmp_ptr;
272          for (p = list->head; p; p = p->next)          for (cur = list->head; cur; cur = cur->next)
273                  if (cmp(p->data, data) == 0)                  if (cmp(cur->data, data) == 0)
274                          break;                          break;
275          if (p == list->cur)          return cur ? cur->data : NULL;
                 return list_remove_current(list);  
         else  
                 _list_remove_item(list, p);  
         return data;  
 }  
   
 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;  
276  }  }
277    
278  /* EOF */  /* EOF */

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