Start 1.33.0 development cycle
[oweals/busybox.git] / libbb / llist.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * linked list helper functions.
4  *
5  * Copyright (C) 2003 Glenn McGrath
6  * Copyright (C) 2005 Vladimir Oleynik
7  * Copyright (C) 2005 Bernhard Reutner-Fischer
8  * Copyright (C) 2006 Rob Landley <rob@landley.net>
9  *
10  * Licensed under GPLv2 or later, see file LICENSE in this source tree.
11  */
12 #include "libbb.h"
13
14 /* Add data to the start of the linked list.  */
15 void FAST_FUNC llist_add_to(llist_t **old_head, void *data)
16 {
17         llist_t *new_head = xmalloc(sizeof(llist_t));
18
19         new_head->data = data;
20         new_head->link = *old_head;
21         *old_head = new_head;
22 }
23
24 /* Add data to the end of the linked list.  */
25 void FAST_FUNC llist_add_to_end(llist_t **list_head, void *data)
26 {
27         while (*list_head)
28                 list_head = &(*list_head)->link;
29         *list_head = xzalloc(sizeof(llist_t));
30         (*list_head)->data = data;
31         /*(*list_head)->link = NULL;*/
32 }
33
34 /* Remove first element from the list and return it */
35 void* FAST_FUNC llist_pop(llist_t **head)
36 {
37         void *data = NULL;
38         llist_t *temp = *head;
39
40         if (temp) {
41                 data = temp->data;
42                 *head = temp->link;
43                 free(temp);
44         }
45         return data;
46 }
47
48 /* Unlink arbitrary given element from the list */
49 void FAST_FUNC llist_unlink(llist_t **head, llist_t *elm)
50 {
51         if (!elm)
52                 return;
53         while (*head) {
54                 if (*head == elm) {
55                         *head = (*head)->link;
56                         break;
57                 }
58                 head = &(*head)->link;
59         }
60 }
61
62 /* Recursively free all elements in the linked list.  If freeit != NULL
63  * call it on each datum in the list */
64 void FAST_FUNC llist_free(llist_t *elm, void (*freeit)(void *data))
65 {
66         while (elm) {
67                 void *data = llist_pop(&elm);
68
69                 if (freeit)
70                         freeit(data);
71         }
72 }
73
74 /* Reverse list order. */
75 llist_t* FAST_FUNC llist_rev(llist_t *list)
76 {
77         llist_t *rev = NULL;
78
79         while (list) {
80                 llist_t *next = list->link;
81
82                 list->link = rev;
83                 rev = list;
84                 list = next;
85         }
86         return rev;
87 }
88
89 llist_t* FAST_FUNC llist_find_str(llist_t *list, const char *str)
90 {
91         while (list) {
92                 if (strcmp(list->data, str) == 0)
93                         break;
94                 list = list->link;
95         }
96         return list;
97 }