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. */ 16void 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. */ 26void FAST_FUNC llist_add_to_end(llist_t **list_head, void *data) 27{ 28 llist_t *new_item = xmalloc(sizeof(llist_t)); 29 30 new_item->data = data; 31 new_item->link = NULL; 32 33 if (!*list_head) 34 *list_head = new_item; 35 else { 36 llist_t *tail = *list_head; 37 38 while (tail->link) 39 tail = tail->link; 40 tail->link = new_item; 41 } 42} 43 44/* Remove first element from the list and return it */ 45void* FAST_FUNC llist_pop(llist_t **head) 46{ 47 void *data, *next; 48 49 if (!*head) 50 return NULL; 51 52 data = (*head)->data; 53 next = (*head)->link; 54 free(*head); 55 *head = next; 56 57 return data; 58} 59 60/* Unlink arbitrary given element from the list */ 61void FAST_FUNC llist_unlink(llist_t **head, llist_t *elm) 62{ 63 llist_t *crt; 64 65 if (!(elm && *head)) 66 return; 67 68 if (elm == *head) { 69 *head = (*head)->link; 70 return; 71 } 72 73 for (crt = *head; crt; crt = crt->link) { 74 if (crt->link == elm) { 75 crt->link = elm->link; 76 return; 77 } 78 } 79} 80 81/* Recursively free all elements in the linked list. If freeit != NULL 82 * call it on each datum in the list */ 83void FAST_FUNC llist_free(llist_t *elm, void (*freeit) (void *data)) 84{ 85 while (elm) { 86 void *data = llist_pop(&elm); 87 88 if (freeit) 89 freeit(data); 90 } 91} 92 93/* Reverse list order. */ 94llist_t* FAST_FUNC llist_rev(llist_t *list) 95{ 96 llist_t *rev = NULL; 97 98 while (list) { 99 llist_t *next = list->link; 100 101 list->link = rev; 102 rev = list; 103 list = next; 104 } 105 return rev; 106} 107