libbb: shrink linked list ops (by xmaks AT email.cz)
[platform/upstream/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 the GPL v2 or later, see the file LICENSE in this tarball.
11  */
12
13 #include "libbb.h"
14
15 /* Add data to the start of the linked list.  */
16 void FAST_FUNC llist_add_to(llist_t **old_head, void *data)
17 {
18         llist_t *new_head = xmalloc(sizeof(llist_t));
19
20         new_head->data = data;
21         new_head->link = *old_head;
22         *old_head = new_head;
23 }
24
25 /* Add data to the end of the linked list.  */
26 void FAST_FUNC llist_add_to_end(llist_t **list_head, void *data)
27 {
28         while (*list_head)
29                 list_head = &(*list_head)->link;
30         *list_head = xzalloc(sizeof(llist_t));
31         (*list_head)->data = data;
32         /*(*list_head)->link = NULL;*/
33 }
34
35 /* Remove first element from the list and return it */
36 void* FAST_FUNC llist_pop(llist_t **head)
37 {
38         void *data = NULL;
39         llist_t *temp = *head;
40
41         if (temp) {
42                 data = temp->data;
43                 *head = temp->link;
44                 free(temp);
45         }
46         return data;
47 }
48
49 /* Unlink arbitrary given element from the list */
50 void FAST_FUNC llist_unlink(llist_t **head, llist_t *elm)
51 {
52         if (!elm)
53                 return;
54         while (*head) {
55                 if (*head == elm) {
56                         *head = (*head)->link;
57                         break;
58                 }
59                 head = &(*head)->link;
60         }
61 }
62
63 /* Recursively free all elements in the linked list.  If freeit != NULL
64  * call it on each datum in the list */
65 void FAST_FUNC llist_free(llist_t *elm, void (*freeit) (void *data))
66 {
67         while (elm) {
68                 void *data = llist_pop(&elm);
69
70                 if (freeit)
71                         freeit(data);
72         }
73 }
74
75 /* Reverse list order. */
76 llist_t* FAST_FUNC llist_rev(llist_t *list)
77 {
78         llist_t *rev = NULL;
79
80         while (list) {
81                 llist_t *next = list->link;
82
83                 list->link = rev;
84                 rev = list;
85                 list = next;
86         }
87         return rev;
88 }