1/* 2 * list.c, list 3 * 4 * Copyright (c) 2009-2010 Wind River Systems, Inc. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19#include <stdlib.h> 20 21#include <list.h> 22 23void __list_init(struct list *entry) 24{ 25 if (entry) { 26 entry->prev = NULL; 27 entry->next = NULL; 28 entry->data = NULL; 29 } 30} 31 32struct list *__list_alloc(void) 33{ 34 struct list *new; 35 36 new = malloc(sizeof(struct list)); 37 __list_init(new); 38 39 return new; 40} 41 42struct list *list_alloc(void *data) 43{ 44 struct list *new; 45 46 new = __list_alloc(); 47 if (new) 48 new->data = data; 49 50 return new; 51} 52 53void __list_free(struct list *entry) 54{ 55 free(entry); 56} 57 58void list_free_all(struct list *list) 59{ 60 struct list *ptr, *tmp; 61 62 list_foreach_safe(list, ptr, tmp) { 63 __list_free(ptr); 64 } 65} 66 67struct list *__list_last(struct list *list) 68{ 69 if (list) 70 while (list->next) 71 list = list->next; 72 73 return list; 74} 75 76struct list *__list_first(struct list *list) 77{ 78 if (list) 79 while (list->prev) 80 list = list->prev; 81 82 return list; 83} 84 85struct list *__list_entry(struct list *list, int index) 86{ 87 struct list *entry; 88 int i = 0; 89 90 list_foreach(list, entry) { 91 if (i == index) 92 break; 93 i++; 94 } 95 96 return entry; 97} 98 99int list_length(struct list *list) 100{ 101 int length = 0; 102 103 while (list) { 104 list = list->next; 105 length++; 106 } 107 108 return length; 109} 110 111struct list *__list_add_before(struct list *entry, struct list *new) 112{ 113 struct list *prev; 114 115 if (entry) { 116 prev = entry->prev; 117 if (prev) 118 prev->next = new; 119 new->prev = prev; 120 new->next = entry; 121 entry->prev = new; 122 } 123 124 return new; 125} 126 127struct list *__list_add_after(struct list *entry, struct list *new) 128{ 129 struct list *next; 130 131 if (entry) { 132 next = entry->next; 133 if (next) 134 next->prev = new; 135 new->next = next; 136 new->prev = entry; 137 entry->next = new; 138 139 return entry; 140 } 141 142 return new; 143} 144 145struct list *__list_add_head(struct list *list, struct list *new) 146{ 147 struct list *first; 148 149 if (list) { 150 first = __list_first(list); 151 __list_add_before(first, new); 152 } 153 154 return new; 155} 156 157struct list *__list_add_tail(struct list *list, struct list *new) 158{ 159 struct list *last; 160 161 if (list) { 162 last = __list_last(list); 163 __list_add_after(last, new); 164 165 return list; 166 } 167 else 168 return new; 169} 170 171struct list *list_add_head(struct list *list, void *data) 172{ 173 struct list *new; 174 175 new = list_alloc(data); 176 if (!new) 177 return NULL; 178 179 return __list_add_head(list, new); 180} 181 182struct list *list_add_tail(struct list *list, void *data) 183{ 184 struct list *new; 185 186 new = list_alloc(data); 187 if (!new) 188 return NULL; 189 190 return __list_add_tail(list, new); 191} 192 193struct list *__list_remove(struct list *list, struct list *entry) 194{ 195 struct list *prev, *next; 196 197 if (entry) { 198 prev = entry->prev; 199 next = entry->next; 200 201 if (prev) 202 prev->next = next; 203 else 204 list = next; 205 if (next) 206 next->prev = prev; 207 208 entry->prev = NULL; 209 entry->next = NULL; 210 } 211 212 return list; 213} 214 215struct list *__list_delete(struct list *list, 216 struct list *entry) 217{ 218 list = __list_remove(list, entry); 219 __list_free(entry); 220 221 return list; 222} 223 224struct list *list_delete(struct list *list, void *data) 225{ 226 struct list *ptr, *tmp; 227 228 list_foreach_safe(list, ptr, tmp) { 229 if (ptr->data == data) { 230 list = __list_delete(list, ptr); 231 break; 232 } 233 } 234 235 return list; 236} 237 238struct list *list_delete_all(struct list *list, void *data) 239{ 240 struct list *ptr, *tmp; 241 242 list_foreach_safe(list, ptr, tmp) { 243 if (ptr->data == data) 244 list = __list_delete(list, ptr); 245 } 246 247 return list; 248} 249 250struct list *list_find(struct list *list, void *data) 251{ 252 struct list *ptr; 253 254 list_foreach(list, ptr) { 255 if (ptr->data == data) 256 break; 257 } 258 259 return ptr; 260} 261 262struct list *list_find_reverse(struct list *list, void *data) 263{ 264 struct list *ptr; 265 266 list_foreach_reverse(list, ptr) { 267 if (ptr->data == data) 268 break; 269 } 270 271 return ptr; 272} 273