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 
13 #include "libbb.h"
14 
15 /* Add data to the start of the linked list.  */
llist_add_to(llist_t ** old_head,void * data)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.  */
llist_add_to_end(llist_t ** list_head,void * data)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 */
llist_pop(llist_t ** head)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 */
llist_unlink(llist_t ** head,llist_t * elm)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 */
llist_free(llist_t * elm,void (* freeit)(void * data))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. */
llist_rev(llist_t * list)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 }
89 
llist_find_str(llist_t * list,const char * str)90 llist_t* FAST_FUNC llist_find_str(llist_t *list, const char *str)
91 {
92 	while (list) {
93 		if (strcmp(list->data, str) == 0)
94 			break;
95 		list = list->link;
96 	}
97 	return list;
98 }
99