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