- Changed list routines to give it the same look'n'feel as the rbl and
authorGuus Sliepen <guus@tinc-vpn.org>
Sun, 7 Jan 2001 15:24:52 +0000 (15:24 +0000)
committerGuus Sliepen <guus@tinc-vpn.org>
Sun, 7 Jan 2001 15:24:52 +0000 (15:24 +0000)
  avl tree library.

lib/list.c
lib/list.h

index f509e21..d317622 100644 (file)
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: list.c,v 1.1.2.6 2000/11/22 23:09:38 guus Exp $
+    $Id: list.c,v 1.1.2.7 2001/01/07 15:24:52 guus Exp $
 */
 
 #include "config.h"
 
 #include <stdlib.h>
-#include <string.h>
-#include <syslog.h>
 
-#include <list.h>
 #include <xalloc.h>
-
 #include <system.h>
 
-/*
-  list_new
+#include "list.h"
 
-  Initialize a new list.
-*/
-list_t *list_new(void)
+/* (De)constructors */
+
+list_t *list_alloc(list_action_t delete)
 {
   list_t *list;
 
   list = xmalloc_and_zero(sizeof(list_t));
+  list->delete = delete;
+
   return list;
 }
 
-/*
-  list_delete
+void list_free(list_t *list)
+{
+  free(list);
+}
 
-  Delete the element pointed to by idx from the list.
-*/
-void list_delete(list_t *list, list_node_t *idx)
+list_node_t *list_alloc_node(void)
 {
-  if(!list || !idx)
-    return;
+  list_node_t *node;
+  
+  node = xmalloc_and_zero(sizeof(list_node_t));
+  
+  return node;
+}
 
-  if(list->callbacks->delete != NULL)
-    if(list->callbacks->delete(idx->data))
-      syslog(LOG_WARNING, _("List callback[delete] failed for %08lx - freeing anyway"), idx->data);
+void list_free_node(list_t *list, list_node_t *node)
+{
+  if(node->data && list->delete)
+    list->delete(node->data);
   
-  free(idx->data);
+  free(node->data);
+}
+
+/* Insertion and deletion */
+
+list_node_t *list_insert_head(list_t *list, void *data)
+{
+  list_node_t *node;
   
-  if(idx->prev == NULL)
-    /* First element in list */
-    {
-      list->head = idx->next;
-    }
-  if(idx->next == NULL)
-    /* Last element in list */
-    {
-      list->tail = idx->prev;
-    }
-  if(idx->prev != NULL && idx->next != NULL)
-    /* Neither first nor last element */
-    {
-      idx->prev->next = idx->next;
-      idx->next->prev = idx->prev;
-    }
-  if(list->head == NULL)
-    list->tail = NULL;
+  node = list_alloc_node();
+  
+  node->data = data;
+  node->prev = NULL;
+  node->next = list->head;
+  list->head = node;
+  
+  if(node->next)
+    node->next->prev = node;
   else
-    if(list->tail == NULL)
-      list->head = NULL;
+    list->tail = node;
 
-  free(idx);
+  return node;
 }
 
-/*
-  list_forall_nodes
+list_node_t *list_insert_tail(list_t *list, void *data)
+{
+  list_node_t *node;
+  
+  node = list_alloc_node();
+  
+  node->data = data;
+  node->next = NULL;
+  node->prev = list->tail;
+  list->tail = node;
+  
+  if(node->prev)
+    node->prev->next = node;
+  else
+    list->head = node;
 
-  Call function() on each element in the list.  If this function
-  returns non-zero, the element will be removed from the list.
-*/
-void list_forall_nodes(list_t *list, int (*function)(void *data))
+  return node;
+}
+
+void list_unlink_node(list_t *list, list_node_t *node)
 {
-  list_node_t *p, *next;
-  int res;
+  if(node->prev)
+    node->prev->next = node->next;
+  else
+    list->head = node->next;
+    
+  if(node->next)
+    node->next->prev = node->prev;
+  else
+    list->tail = node->prev;
+}
+
+void list_delete_node(list_t *list, list_node_t *node)
+{
+  list_unlink_node(list, node);
+  list_free_node(list, node);
+}
+
+void list_delete_head(list_t *list)
+{
+  list_delete_node(list, list->head);
+}
+
+void list_delete_tail(list_t *list)
+{
+  list_delete_node(list, list->tail);
+}
+
+/* Head/tail lookup */
+
+void *list_get_head(list_t *list)
+{
+  if(list->head)
+    return list->head->data;
+  else
+    return NULL;
+}
+
+void *list_get_tail(list_t *list)
+{
+  if(list->tail)
+    return list->tail->data;
+  else
+    return NULL;
+}
+
+/* Fast list deletion */
+
+void list_delete_list(list_t *list)
+{
+  list_node_t *node, *next;
   
-  if(!list)       /* no list given */
-    return;
-  if(!function)   /* no function given */
-    return;
-  if(!list->head) /* list is empty */
-    return;
-  for(p = list->head; p != NULL; p = next)
+  for(node = list->head; node; node = next)
     {
-      next = p->next;
-      res = function(p->data);
-      if(res != 0)
-       list_delete(list, p);
+      next = node->next;
+      list_free_node(list, node);
     }
+
+  list_free(list);
 }
 
-/*
-  list_destroy
+/* Traversing */
 
-  Free all datastructures contained in this list.  It uses the delete
-  callback for this list to free each element.
-*/
-void list_destroy(list_t *list)
+void list_foreach_node(list_t *list, list_action_node_t action)
 {
-  if(!list)
-    return;
-/*  list_destroy_nodes(list); */
-  free(list);
-}
+  list_node_t *node, *next;
 
-/*
-  list_append
+  for(node = list->head; node; node = next)
+    {
+      next = node->next;
+      action(node);
+    }
+}
 
-  Append a new node to the list that points to data.
-*/
-void list_append(list_t *list, void *data)
+void list_foreach(list_t *list, list_action_t action)
 {
-  list_node_t *n;
+  list_node_t *node, *next;
 
-  n = xmalloc_and_zero(sizeof(list_node_t));
-  n->data = data;
-  n->prev = list->tail;
-  if(list->tail)
-    list->tail->next = n;
-  list->tail = n;
+  for(node = list->head; node; node = next)
+    {
+      next = node->next;
+      if(node->data)
+        action(node->data);
+    }
 }
index 86e17e6..960a909 100644 (file)
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: list.h,v 1.1.2.2 2000/11/16 22:13:09 zarq Exp $
+    $Id: list.h,v 1.1.2.3 2001/01/07 15:24:52 guus Exp $
 */
 
 #ifndef __TINC_LIST_H__
 #define __TINC_LIST_H__
 
-typedef struct list_callbacks_t {
-  int (*delete) (void *);
-} list_callbacks_t;
-
-typedef struct list_node_t {
-  void *data;
+typedef struct list_node_t
+{
   struct list_node_t *prev;
   struct list_node_t *next;
+
+  /* Payload */
+
+  void *data;
 } list_node_t;
 
-typedef struct list_t {
+typedef void (*list_action_t) (const void *);
+typedef void (*list_action_node_t) (const list_node_t *);
+
+typedef struct list_t
+{
   list_node_t *head;
   list_node_t *tail;
-  list_callbacks_t *callbacks;
+
+  /* Callbacks */
+
+  list_action_t delete;
 } list_t;
 
-extern list_t *list_new(void);
-extern void list_append(list_t *, void *);
-extern void list_forall_nodes(list_t *, int (*)(void *));
+/* (De)constructors */
+
+extern list_t *list_alloc(list_action_t);
+extern void list_free(list_t *);
+extern list_node_t *list_alloc_node(void);
+extern void list_free_node(list_t *, list_node_t *);
+
+/* Insertion and deletion */
+
+extern list_node_t *list_insert_head(list_t *, void *);
+extern list_node_t *list_insert_tail(list_t *, void *);
+
+extern void list_unlink_node(list_t *, list_node_t *);
+extern void list_delete_node(list_t *, list_node_t *);
+
+extern void list_delete_head(list_t *);
+extern void list_delete_tail(list_t *);
+
+/* Head/tail lookup */
+
+extern void *list_get_head(list_t *);
+extern void *list_get_tail(list_t *);
+
+/* Fast list deletion */
+
+extern void list_delete_list(list_t *);
+
+/* Traversing */
 
+extern void list_foreach(list_t *, list_action_t);
+extern void list_foreach_node(list_t *, list_action_node_t);
 
 #endif /* __TINC_LIST_H__ */