Fix FreeBSD build.
[haiku.git] / src / tools / fs_shell / list.cpp
blob6e70e5d23814510150021b9a324a1fbd3552b61e
1 /*
2 * Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
7 #include "list.h"
10 #define GET_ITEM(list, item) ((void *)((uint8_t *)item - list->offset))
11 #define GET_LINK(list, item) ((list_link *)((uint8_t *)item + list->offset))
14 namespace FSShell {
17 /** Initializes the list with a specified offset to the link
18 * structure in the items that will be part of the list.
21 void
22 list_init_etc(struct list *list, int32_t offset)
24 list->link.next = list->link.prev = &list->link;
25 list->offset = offset;
29 void
30 list_init(struct list *list)
32 list_init_etc(list, 0);
36 /** Adds a link to the head of the list
39 void
40 list_add_link_to_head(struct list *list, void *_link)
42 list_link *link = (list_link *)_link;
44 link->next = list->link.next;
45 link->prev = &list->link;
47 list->link.next->prev = link;
48 list->link.next = link;
52 /** Adds a link to the tail of the list
55 void
56 list_add_link_to_tail(struct list *list, void *_link)
58 list_link *link = (list_link *)_link;
60 link->next = &list->link;
61 link->prev = list->link.prev;
63 list->link.prev->next = link;
64 list->link.prev = link;
68 /** Removes a link from the list it's currently in.
69 * Note: the link has to be in a list when you call this function.
72 void
73 list_remove_link(void *_link)
75 list_link *link = (list_link *)_link;
77 link->next->prev = link->prev;
78 link->prev->next = link->next;
82 static inline list_link *
83 get_next_link(struct list *list, list_link *link)
85 if (link->next == &list->link)
86 return NULL;
88 return link->next;
92 static inline list_link *
93 get_prev_link(struct list *list, list_link *link)
95 if (link->prev == &list->link)
96 return NULL;
98 return link->prev;
102 /** Gets the successor for the current item. If the passed
103 * item is NULL, it returns the first entry in the list,
104 * if there is one.
105 * Returns NULL if there aren't any more items in this list.
108 void *
109 list_get_next_item(struct list *list, void *item)
111 list_link *link;
113 if (item == NULL)
114 return list_is_empty(list) ? NULL : GET_ITEM(list, list->link.next);
116 link = get_next_link(list, GET_LINK(list, item));
117 return link != NULL ? GET_ITEM(list, link) : NULL;
121 /** Gets the predecessor for the current item. If the passed
122 * item is NULL, it returns the last entry in the list,
123 * if there is one.
124 * Returns NULL if there aren't any previous items in this list.
127 void *
128 list_get_prev_item(struct list *list, void *item)
130 list_link *link;
132 if (item == NULL)
133 return list_is_empty(list) ? NULL : GET_ITEM(list, list->link.prev);
135 link = get_prev_link(list, GET_LINK(list, item));
136 return link != NULL ? GET_ITEM(list, link) : NULL;
140 void *
141 list_get_last_item(struct list *list)
143 return list_is_empty(list) ? NULL : GET_ITEM(list, list->link.prev);
147 /** Adds an item to the end of the list.
148 * Similar to list_add_link_to_tail() but works on the item, not the link.
151 void
152 list_add_item(struct list *list, void *item)
154 list_add_link_to_tail(list, GET_LINK(list, item));
158 /** Removes an item from the list.
159 * Similar to list_remove_link() but works on the item, not the link.
162 void
163 list_remove_item(struct list *list, void *item)
165 list_remove_link(GET_LINK(list, item));
169 /** Inserts an item before another item in the list.
170 * If you pass NULL as \a before item, the item is added at the end of
171 * the list.
174 void
175 list_insert_item_before(struct list *list, void *before, void *item)
177 list_link *beforeLink;
178 list_link *link;
180 if (before == NULL) {
181 list_add_item(list, item);
182 return;
185 beforeLink = GET_LINK(list, before);
186 link = GET_LINK(list, item);
188 link->prev = beforeLink->prev;
189 link->next = beforeLink;
191 beforeLink->prev->next = link;
192 beforeLink->prev = link;
196 /** Removes the first item in the list and returns it.
197 * Returns NULL if the list is empty.
200 void *
201 list_remove_head_item(struct list *list)
203 list_link *link;
205 if (list_is_empty(list))
206 return NULL;
208 list_remove_link(link = list->link.next);
209 return GET_ITEM(list, link);
213 /** Removes the last item in the list and returns it.
214 * Returns NULL if the list is empty.
217 void *
218 list_remove_tail_item(struct list *list)
220 list_link *link;
222 if (list_is_empty(list))
223 return NULL;
225 list_remove_link(link = list->link.prev);
226 return GET_ITEM(list, link);
230 /** Moves the contents of the source list to the target list.
231 * The target list will be emptied before the items are moved;
232 * this is a very fast operation.
235 void
236 list_move_to_list(struct list *sourceList, struct list *targetList)
238 if (list_is_empty(sourceList)) {
239 targetList->link.next = targetList->link.prev = &targetList->link;
240 return;
243 *targetList = *sourceList;
245 // correct link pointers to this list
246 targetList->link.next->prev = &targetList->link;
247 targetList->link.prev->next = &targetList->link;
249 // empty source list
250 sourceList->link.next = sourceList->link.prev = &sourceList->link;
253 } // namespace FSShell