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.  */
llist_add_to(llist_t ** old_head,void * data)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.  */
llist_add_to_end(llist_t ** list_head,void * data)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 */
llist_pop(llist_t ** head)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 */
llist_unlink(llist_t ** head,llist_t * elm)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 */
llist_free(llist_t * elm,void (* freeit)(void * data))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. */
llist_rev(llist_t * list)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 
llist_find_str(llist_t * list,const char * str)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 }
98