blob: 094c6524619d26a0ffacca3d36184a240960023c [file] [log] [blame]
Bernhard Reutner-Fischer56b21712005-10-06 12:10:48 +00001/* 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 Fischer
Rob Landleycc848dd2006-05-11 18:25:24 +00008 * Copyright (C) 2006 Rob Landley <rob@landley.net>
Bernhard Reutner-Fischer56b21712005-10-06 12:10:48 +00009 *
Bernhard Reutner-Fischer7fee0c42006-09-13 16:39:19 +000010 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
Bernhard Reutner-Fischer56b21712005-10-06 12:10:48 +000011 */
"Robert P. J. Day"5d8843e2006-07-10 11:41:19 +000012
Bernhard Reutner-Fischerbee9eb12005-09-29 12:55:10 +000013#include "libbb.h"
14
Bernhard Reutner-Fischer56b21712005-10-06 12:10:48 +000015/* Add data to the start of the linked list. */
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +000016void FAST_FUNC llist_add_to(llist_t **old_head, void *data)
Bernhard Reutner-Fischerbee9eb12005-09-29 12:55:10 +000017{
Rob Landley8bb50782006-05-26 23:44:51 +000018 llist_t *new_head = xmalloc(sizeof(llist_t));
Bernhard Reutner-Fischerd909d232007-02-04 20:32:38 +000019
Rob Landley5edc1022006-05-26 23:00:10 +000020 new_head->data = data;
Rob Landley8bb50782006-05-26 23:44:51 +000021 new_head->link = *old_head;
22 *old_head = new_head;
Bernhard Reutner-Fischerbee9eb12005-09-29 12:55:10 +000023}
Bernhard Reutner-Fischerbee9eb12005-09-29 12:55:10 +000024
Bernhard Reutner-Fischer56b21712005-10-06 12:10:48 +000025/* Add data to the end of the linked list. */
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +000026void FAST_FUNC llist_add_to_end(llist_t **list_head, void *data)
Bernhard Reutner-Fischerbee9eb12005-09-29 12:55:10 +000027{
Rob Landley8bb50782006-05-26 23:44:51 +000028 llist_t *new_item = xmalloc(sizeof(llist_t));
Bernhard Reutner-Fischerd909d232007-02-04 20:32:38 +000029
Bernhard Reutner-Fischerbee9eb12005-09-29 12:55:10 +000030 new_item->data = data;
31 new_item->link = NULL;
32
Bernhard Reutner-Fischerd909d232007-02-04 20:32:38 +000033 if (!*list_head)
34 *list_head = new_item;
Rob Landley8bb50782006-05-26 23:44:51 +000035 else {
36 llist_t *tail = *list_head;
Bernhard Reutner-Fischerd909d232007-02-04 20:32:38 +000037
38 while (tail->link)
39 tail = tail->link;
Bernhard Reutner-Fischer56b21712005-10-06 12:10:48 +000040 tail->link = new_item;
Bernhard Reutner-Fischerbee9eb12005-09-29 12:55:10 +000041 }
Bernhard Reutner-Fischerbee9eb12005-09-29 12:55:10 +000042}
Bernhard Reutner-Fischerbee9eb12005-09-29 12:55:10 +000043
Rob Landleya6b5b602006-05-08 19:03:07 +000044/* Remove first element from the list and return it */
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +000045void* FAST_FUNC llist_pop(llist_t **head)
Bernhard Reutner-Fischer56b21712005-10-06 12:10:48 +000046{
Denis Vlasenkoc115fdb2007-03-06 22:53:10 +000047 void *data, *next;
Rob Landleya6b5b602006-05-08 19:03:07 +000048
Bernhard Reutner-Fischerd909d232007-02-04 20:32:38 +000049 if (!*head)
Denis Vlasenkoc115fdb2007-03-06 22:53:10 +000050 return NULL;
Bernhard Reutner-Fischerd909d232007-02-04 20:32:38 +000051
Denis Vlasenkoc115fdb2007-03-06 22:53:10 +000052 data = (*head)->data;
53 next = (*head)->link;
54 free(*head);
55 *head = next;
Rob Landleya6b5b602006-05-08 19:03:07 +000056
57 return data;
Bernhard Reutner-Fischer56b21712005-10-06 12:10:48 +000058}
Bernhard Reutner-Fischer56b21712005-10-06 12:10:48 +000059
Denis Vlasenkoc115fdb2007-03-06 22:53:10 +000060/* Unlink arbitrary given element from the list */
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +000061void FAST_FUNC llist_unlink(llist_t **head, llist_t *elm)
Denis Vlasenkoc115fdb2007-03-06 22:53:10 +000062{
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
Rob Landleya6b5b602006-05-08 19:03:07 +000081/* Recursively free all elements in the linked list. If freeit != NULL
82 * call it on each datum in the list */
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +000083void FAST_FUNC llist_free(llist_t *elm, void (*freeit) (void *data))
Bernhard Reutner-Fischer56b21712005-10-06 12:10:48 +000084{
Rob Landleya6b5b602006-05-08 19:03:07 +000085 while (elm) {
86 void *data = llist_pop(&elm);
Bernhard Reutner-Fischerd909d232007-02-04 20:32:38 +000087
88 if (freeit)
89 freeit(data);
Rob Landleya6b5b602006-05-08 19:03:07 +000090 }
Bernhard Reutner-Fischer56b21712005-10-06 12:10:48 +000091}
Denis Vlasenkoc8400a22006-10-25 00:33:44 +000092
Denis Vlasenko8d9f4952007-04-08 15:08:42 +000093#ifdef UNUSED
94/* Reverse list order. */
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +000095llist_t* FAST_FUNC llist_rev(llist_t *list)
Denis Vlasenkoc8400a22006-10-25 00:33:44 +000096{
Denis Vlasenko8d9f4952007-04-08 15:08:42 +000097 llist_t *rev = NULL;
Bernhard Reutner-Fischerd909d232007-02-04 20:32:38 +000098
Denis Vlasenkoc8400a22006-10-25 00:33:44 +000099 while (list) {
100 llist_t *next = list->link;
Bernhard Reutner-Fischerd909d232007-02-04 20:32:38 +0000101
Denis Vlasenko8d9f4952007-04-08 15:08:42 +0000102 list->link = rev;
103 rev = list;
Denis Vlasenkoc8400a22006-10-25 00:33:44 +0000104 list = next;
105 }
Denis Vlasenko8d9f4952007-04-08 15:08:42 +0000106 return rev;
Denis Vlasenkoc8400a22006-10-25 00:33:44 +0000107}
Denis Vlasenko8d9f4952007-04-08 15:08:42 +0000108#endif