]>
Commit | Line | Data |
---|---|---|
250b1eec SG |
1 | /* |
2 | * lxc: linux Container library | |
3 | * | |
4 | * (C) Copyright IBM Corp. 2007, 2008 | |
5 | * | |
6 | * Authors: | |
7 | * Daniel Lezcano <daniel.lezcano at free.fr> | |
8 | * | |
9 | * This library is free software; you can redistribute it and/or | |
10 | * modify it under the terms of the GNU Lesser General Public | |
11 | * License as published by the Free Software Foundation; either | |
12 | * version 2.1 of the License, or (at your option) any later version. | |
13 | * | |
14 | * This library is distributed in the hope that it will be useful, | |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
17 | * Lesser General Public License for more details. | |
18 | * | |
19 | * You should have received a copy of the GNU Lesser General Public | |
20 | * License along with this library; if not, write to the Free Software | |
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
22 | */ | |
23 | ||
f1a4a029 ÇO |
24 | #ifndef __LXC_LIST_H |
25 | #define __LXC_LIST_H | |
0ad19a3f | 26 | |
951cc719 | 27 | struct lxc_list { |
0ad19a3f | 28 | void *elem; |
951cc719 DL |
29 | struct lxc_list *next; |
30 | struct lxc_list *prev; | |
0ad19a3f | 31 | }; |
32 | ||
951cc719 | 33 | #define lxc_init_list(l) { .next = l, .prev = l } |
0ad19a3f | 34 | |
c2613927 CB |
35 | /* |
36 | * Iterate through an lxc list. An example for an idiom would be: | |
37 | * | |
38 | * struct lxc_list *iterator; | |
39 | * type *tmp; // where "type" can be an int, char * etc. | |
40 | * lxc_list_for_each(iterator, list) { | |
41 | * tmp = iterator->elem; | |
42 | * // Do stuff with tmp. | |
43 | * } | |
44 | * free(iterator); | |
45 | */ | |
951cc719 | 46 | #define lxc_list_for_each(__iterator, __list) \ |
0ad19a3f | 47 | for (__iterator = (__list)->next; \ |
48 | __iterator != __list; \ | |
49 | __iterator = __iterator->next) | |
50 | ||
c2613927 CB |
51 | /* |
52 | * Iterate safely through an lxc list. An example for an appropriate use case | |
53 | * would be: | |
54 | * | |
55 | * struct lxc_list *iterator; | |
56 | * lxc_list_for_each_safe(iterator, list, list->next) { | |
57 | * tmp = iterator->elem; | |
58 | * // Do stuff with tmp. | |
59 | * } | |
60 | * free(iterator); | |
61 | */ | |
9ebb03ad DE |
62 | #define lxc_list_for_each_safe(__iterator, __list, __next) \ |
63 | for (__iterator = (__list)->next, __next = __iterator->next; \ | |
64 | __iterator != __list; \ | |
65 | __iterator = __next, __next = __next->next) | |
66 | ||
c2613927 | 67 | /* Initalize list. */ |
951cc719 | 68 | static inline void lxc_list_init(struct lxc_list *list) |
0ad19a3f | 69 | { |
70 | list->elem = NULL; | |
71 | list->next = list->prev = list; | |
72 | } | |
73 | ||
c2613927 CB |
74 | /* Add an element to a list. See lxc_list_add() and lxc_list_add_tail() for an |
75 | * idiom. */ | |
951cc719 | 76 | static inline void lxc_list_add_elem(struct lxc_list *list, void *elem) |
0ad19a3f | 77 | { |
78 | list->elem = elem; | |
79 | } | |
80 | ||
c2613927 | 81 | /* Retrieve first element of list. */ |
951cc719 | 82 | static inline void *lxc_list_first_elem(struct lxc_list *list) |
0ad19a3f | 83 | { |
84 | return list->next->elem; | |
85 | } | |
86 | ||
c2613927 | 87 | /* Retrieve last element of list. */ |
bac89583 DL |
88 | static inline void *lxc_list_last_elem(struct lxc_list *list) |
89 | { | |
90 | return list->prev->elem; | |
91 | } | |
92 | ||
c2613927 | 93 | /* Determine if list is empty. */ |
951cc719 | 94 | static inline int lxc_list_empty(struct lxc_list *list) |
0ad19a3f | 95 | { |
96 | return list == list->next; | |
97 | } | |
98 | ||
c2613927 | 99 | /* Workhorse to be called from lxc_list_add() and lxc_list_add_tail(). */ |
951cc719 DL |
100 | static inline void __lxc_list_add(struct lxc_list *new, |
101 | struct lxc_list *prev, | |
102 | struct lxc_list *next) | |
0ad19a3f | 103 | { |
d028235d SG |
104 | next->prev = new; |
105 | new->next = next; | |
106 | new->prev = prev; | |
107 | prev->next = new; | |
0ad19a3f | 108 | } |
109 | ||
c2613927 CB |
110 | /* |
111 | * Idiom to add an element to the beginning of an lxc list: | |
112 | * | |
113 | * struct lxc_list *tmp = malloc(sizeof(*tmp)); | |
114 | * if (tmp == NULL) | |
115 | * return 1; | |
116 | * lxc_list_add_elem(tmp, elem); | |
117 | * lxc_list_add(list, tmp); | |
118 | */ | |
951cc719 | 119 | static inline void lxc_list_add(struct lxc_list *head, struct lxc_list *list) |
0ad19a3f | 120 | { |
951cc719 DL |
121 | __lxc_list_add(list, head, head->next); |
122 | } | |
123 | ||
c2613927 CB |
124 | /* |
125 | * Idiom to add an element to the end of an lxc list: | |
126 | * | |
127 | * struct lxc_list *tmp = malloc(sizeof(*tmp)); | |
128 | * if (tmp == NULL) | |
129 | * return 1; | |
130 | * lxc_list_add_elem(tmp, elem); | |
131 | * lxc_list_add_tail(list, tmp); | |
132 | */ | |
951cc719 DL |
133 | static inline void lxc_list_add_tail(struct lxc_list *head, |
134 | struct lxc_list *list) | |
135 | { | |
136 | __lxc_list_add(list, head->prev, head); | |
137 | } | |
138 | ||
c2613927 CB |
139 | /* |
140 | * Idiom to free an lxc list: | |
141 | * | |
142 | * lxc_list_for_each_safe(iterator, list, list->next) { | |
143 | * lxc_list_del(iterator); | |
144 | * free(iterator); | |
145 | * } | |
146 | * free(iterator); | |
147 | */ | |
951cc719 DL |
148 | static inline void lxc_list_del(struct lxc_list *list) |
149 | { | |
150 | struct lxc_list *next, *prev; | |
0ad19a3f | 151 | |
152 | next = list->next; | |
153 | prev = list->prev; | |
154 | next->prev = prev; | |
155 | prev->next = next; | |
156 | } | |
157 | ||
c2613927 CB |
158 | /* Return length of the list. */ |
159 | static inline size_t lxc_list_len(struct lxc_list *list) | |
9fc7f8c0 | 160 | { |
c2613927 | 161 | size_t i = 0; |
9fc7f8c0 TA |
162 | struct lxc_list *iter; |
163 | lxc_list_for_each(iter, list) { | |
164 | i++; | |
165 | } | |
166 | ||
167 | return i; | |
168 | } | |
169 | ||
0ad19a3f | 170 | #endif |