libisdn
dlist.c
Go to the documentation of this file.
00001 /*
00002  *
00003  *
00004  */
00005 #ifdef HAVE_CONFIG_H
00006 #include "config.h"
00007 #endif
00008 
00009 #include <stdlib.h>
00010 
00011 #include "common.h"
00012 #include "dlist.h"
00013 
00014 
00015 void dlist_init_head(struct dlist_head *h)
00016 {
00017         h->head = h;
00018         h->next = h;
00019         h->prev = h;
00020 }
00021 
00022 void dlist_init(struct dlist_head *e)
00023 {
00024         e->head = NULL;
00025         e->next = NULL;
00026         e->prev = NULL;
00027 }
00028 
00029 void dlist_insert_after(struct dlist_head *elem, struct dlist_head *enew)
00030 {
00031         enew->head = elem->head;
00032         enew->prev = elem;
00033 
00034         if (elem->next == elem->head) {
00035                 enew->next = enew->head;
00036                 enew->head->prev = enew;        // last element in list, update pointer in head
00037         } else {
00038                 elem->next->prev = enew;
00039                 enew->next = elem->next;
00040         }
00041 
00042         elem->next = enew;
00043 }
00044 
00045 
00046 void dlist_insert_before(struct dlist_head *elem, struct dlist_head *enew)
00047 {
00048         /*
00049          * Cannot insert before list head
00050          */
00051         if (elem->head == elem)
00052                 return;
00053 
00054         enew->head = elem->head;
00055         enew->prev = elem->prev;
00056         elem->prev->next = enew;
00057         elem->prev = enew;
00058         enew->next = elem;
00059 }
00060 
00061 void dlist_insert_tail(struct dlist_head *list, struct dlist_head *enew)
00062 {
00063         if (list->head->prev == NULL) {
00064                 /* empty list */
00065                 enew->head = list->head;
00066                 enew->prev = list->head;
00067                 enew->next = list->head;
00068                 list->head->prev = enew;
00069                 list->head->next = enew;
00070                 return;
00071         }
00072 
00073         if (list->head->prev == list->head)
00074                 dlist_insert_after(list->head, enew);
00075         else
00076                 dlist_insert_after(list->head->prev, enew);
00077 }
00078 
00079 void dlist_remove(struct dlist_head *elem)
00080 {
00081         /*
00082          * Cannot remove list head
00083          */
00084         if (elem->head == elem)
00085                 return;
00086 
00087         if (elem->next != elem->head) {
00088                 elem->prev->next = elem->next;
00089                 elem->next->prev = elem->prev;
00090         } else {
00091                 elem->prev->next = elem->head;
00092                 elem->head->prev = elem->prev;  // was last element in list, update head pointer
00093         }
00094 }
00095 
00096 struct dlist_head *dlist_first(const struct dlist_head *list)
00097 {
00098         if (list->head && list->head->next != list->head)
00099                 return list->head->next;
00100 
00101         return NULL;
00102 }
00103 
00104 struct dlist_head *dlist_last(const struct dlist_head *list)
00105 {
00106         if (list->prev && list->head->prev != list->head)
00107                 return list->head->prev;
00108 
00109         return NULL;
00110 }
00111 
00112 struct dlist_head *dlist_next(const struct dlist_head *elem)
00113 {
00114         if (elem->next != elem->head)
00115                 return elem->next;
00116 
00117         return NULL;
00118 }
00119 
00120 struct dlist_head *dlist_prev(const struct dlist_head *elem)
00121 {
00122         if (elem->prev && elem->head != elem)
00123                 return elem->prev;
00124 
00125         return NULL;
00126 }
00127 
00128 struct dlist_head *dlist_pop_head(const struct dlist_head *elem)
00129 {
00130         struct dlist_head *h = dlist_first(elem);
00131         if (h) dlist_remove(h);
00132         return h;
00133 }
00134 
00135 struct dlist_head *dlist_pop_tail(const struct dlist_head *elem)
00136 {
00137         struct dlist_head *h = dlist_last(elem);
00138         if (h) dlist_remove(h);
00139         return h;
00140 }
00141 
00142 int dlist_is_head(const struct dlist_head *elem)
00143 {
00144         return (elem->head == elem);
00145 }
00146 
00147 
00148 int dlist_is_first(const struct dlist_head *elem)
00149 {
00150         return (elem->prev == elem->head);
00151 }
00152 
00153 
00154 int dlist_is_last(const struct dlist_head *elem)
00155 {
00156         return (elem->next == elem->head);
00157 }
00158 
00159 void dlist_replace(struct dlist_head *old, struct dlist_head *enew)
00160 {
00161         enew->next = old->next;
00162         if (old->next != old->head)
00163                 enew->next->prev = enew;
00164 
00165         enew->prev = old->prev;
00166         enew->prev->next = enew;
00167 
00168         enew->head = old->head;
00169 }