2 * Copyright 2013 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.1 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://floralicense.org/license/
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
25 * This dlist is called Modified Doubly Linked List.
27 * Noramlly, The dobule linked list contains address of previous and next element.
28 * This dlist also contains them, but the tail element only contains prev address.
30 * The head element's prev pointer indicates the last element.
31 * But the last element's next pointer indicates NIL.
33 * So we can find the last element while crawling this DList
34 * But we have to remember the address of the head element.
43 struct dlist *dlist_append(struct dlist *list, void *data)
47 item = malloc(sizeof(*item));
60 item->prev = list->prev;
61 item->prev->next = item;
65 assert(!list->prev->next && "item NEXT");
70 struct dlist *dlist_prepend(struct dlist *list, void *data)
74 item = malloc(sizeof(*item));
85 if (list->prev->next) {
86 list->prev->next = item;
89 item->prev = list->prev;
99 struct dlist *dlist_remove(struct dlist *list, struct dlist *l)
108 l->prev->next = l->next;
112 l->next->prev = l->prev;
116 * If the removed entry 'l' has no next element, it is the last element.
117 * In this case, check the existence of the list first,
118 * and if the list is not empty, update the 'prev' of the list (which is a head element of the list)
120 * If we didn't care about this, the head element(list) can indicates the invalid element.
123 list->prev = l->prev;
130 struct dlist *dlist_find_data(struct dlist *list, void *data)
135 dlist_foreach(list, l, _data) {
144 void *dlist_data(struct dlist *l)
146 return l ? l->data : NULL;
149 struct dlist *dlist_next(struct dlist *l)
151 return l ? l->next : NULL;
154 struct dlist *dlist_prev(struct dlist *l)
156 return l ? l->prev : NULL;
159 int dlist_count(struct dlist *l)
166 dlist_foreach(l, n, data) {
173 struct dlist *dlist_nth(struct dlist *l, int nth)
179 for (n = l; n; n = n->next) {