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