libisdn
|
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 }