list.c revision e4197969e018f1f455d8a99ebabd51994b150506
1/* 2 * Copyright (C) 2009 Wind River Systems 3 * Author: Ho-Eun Ryu <ho-eun.ryu@windriver.com> 4 */ 5 6#include <stdlib.h> 7 8#include <list.h> 9 10void __list_init(struct list *entry) 11{ 12 if (entry) { 13 entry->prev = NULL; 14 entry->next = NULL; 15 entry->data = NULL; 16 } 17} 18 19struct list *__list_alloc(void) 20{ 21 struct list *new; 22 23 new = malloc(sizeof(struct list)); 24 __list_init(new); 25 26 return new; 27} 28 29struct list *list_alloc(void *data) 30{ 31 struct list *new; 32 33 new = __list_alloc(); 34 if (new) 35 new->data = data; 36 37 return new; 38} 39 40void __list_free(struct list *entry) 41{ 42 free(entry); 43} 44 45void list_free_all(struct list *list) 46{ 47 struct list *ptr, *tmp; 48 49 list_foreach_safe(list, ptr, tmp) { 50 __list_free(ptr); 51 } 52} 53 54struct list *__list_last(struct list *list) 55{ 56 if (list) 57 while (list->next) 58 list = list->next; 59 60 return list; 61} 62 63struct list *__list_first(struct list *list) 64{ 65 if (list) 66 while (list->prev) 67 list = list->prev; 68 69 return list; 70} 71 72struct list *__list_entry(struct list *list, int index) 73{ 74 struct list *entry; 75 int i = 0; 76 77 list_foreach(list, entry) { 78 if (i == index) 79 break; 80 i++; 81 } 82 83 return entry; 84} 85 86int list_length(struct list *list) 87{ 88 int length = 0; 89 90 while (list) { 91 list = list->next; 92 length++; 93 } 94 95 return length; 96} 97 98struct list *__list_add_before(struct list *entry, struct list *new) 99{ 100 struct list *prev; 101 102 if (entry) { 103 prev = entry->prev; 104 if (prev) 105 prev->next = new; 106 new->prev = prev; 107 new->next = entry; 108 entry->prev = new; 109 } 110 111 return new; 112} 113 114struct list *__list_add_after(struct list *entry, struct list *new) 115{ 116 struct list *next; 117 118 if (entry) { 119 next = entry->next; 120 if (next) 121 next->prev = new; 122 new->next = next; 123 new->prev = entry; 124 entry->next = new; 125 126 return entry; 127 } 128 129 return new; 130} 131 132struct list *__list_add_head(struct list *list, struct list *new) 133{ 134 struct list *first; 135 136 if (list) { 137 first = __list_first(list); 138 __list_add_before(first, new); 139 } 140 141 return new; 142} 143 144struct list *__list_add_tail(struct list *list, struct list *new) 145{ 146 struct list *last; 147 148 if (list) { 149 last = __list_last(list); 150 __list_add_after(last, new); 151 152 return list; 153 } 154 else 155 return new; 156} 157 158struct list *list_add_head(struct list *list, void *data) 159{ 160 struct list *new; 161 162 new = list_alloc(data); 163 if (!new) 164 return NULL; 165 166 return __list_add_head(list, new); 167} 168 169struct list *list_add_tail(struct list *list, void *data) 170{ 171 struct list *new; 172 173 new = list_alloc(data); 174 if (!new) 175 return NULL; 176 177 return __list_add_tail(list, new); 178} 179 180struct list *__list_remove(struct list *list, struct list *entry) 181{ 182 struct list *prev, *next; 183 184 if (entry) { 185 prev = entry->prev; 186 next = entry->next; 187 188 if (prev) 189 prev->next = next; 190 else 191 list = next; 192 if (next) 193 next->prev = prev; 194 195 entry->prev = NULL; 196 entry->next = NULL; 197 } 198 199 return list; 200} 201 202struct list *__list_delete(struct list *list, 203 struct list *entry) 204{ 205 list = __list_remove(list, entry); 206 __list_free(entry); 207 208 return list; 209} 210 211struct list *list_delete(struct list *list, void *data) 212{ 213 struct list *ptr, *tmp; 214 215 list_foreach_safe(list, ptr, tmp) { 216 if (ptr->data == data) { 217 list = __list_delete(list, ptr); 218 break; 219 } 220 } 221 222 return list; 223} 224 225struct list *list_delete_all(struct list *list, void *data) 226{ 227 struct list *ptr, *tmp; 228 229 list_foreach_safe(list, ptr, tmp) { 230 if (ptr->data == data) 231 list = __list_delete(list, ptr); 232 } 233 234 return list; 235} 236 237struct list *list_find(struct list *list, void *data) 238{ 239 struct list *ptr; 240 241 list_foreach(list, ptr) { 242 if (ptr->data == data) 243 break; 244 } 245 246 return ptr; 247} 248 249struct list *list_find_reverse(struct list *list, void *data) 250{ 251 struct list *ptr; 252 253 list_foreach_reverse(list, ptr) { 254 if (ptr->data == data) 255 break; 256 } 257 258 return ptr; 259} 260