blob: 51b1ce6c99c979dc9741818fffd64ab341f4598d [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
Bernhard Reutner-Fischer6c4dade2008-09-25 12:13:34 +00007 * Copyright (C) 2005 Bernhard Reutner-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{
Denis Vlasenko1265df12009-01-13 15:22:50 +000028 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;*/
Bernhard Reutner-Fischerbee9eb12005-09-29 12:55:10 +000033}
Bernhard Reutner-Fischerbee9eb12005-09-29 12:55:10 +000034
Rob Landleya6b5b602006-05-08 19:03:07 +000035/* Remove first element from the list and return it */
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +000036void* FAST_FUNC llist_pop(llist_t **head)
Bernhard Reutner-Fischer56b21712005-10-06 12:10:48 +000037{
Denis Vlasenko1265df12009-01-13 15:22:50 +000038 void *data = NULL;
39 llist_t *temp = *head;
Rob Landleya6b5b602006-05-08 19:03:07 +000040
Denis Vlasenko1265df12009-01-13 15:22:50 +000041 if (temp) {
42 data = temp->data;
43 *head = temp->link;
44 free(temp);
45 }
Rob Landleya6b5b602006-05-08 19:03:07 +000046 return data;
Bernhard Reutner-Fischer56b21712005-10-06 12:10:48 +000047}
Bernhard Reutner-Fischer56b21712005-10-06 12:10:48 +000048
Denis Vlasenkoc115fdb2007-03-06 22:53:10 +000049/* Unlink arbitrary given element from the list */
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +000050void FAST_FUNC llist_unlink(llist_t **head, llist_t *elm)
Denis Vlasenkoc115fdb2007-03-06 22:53:10 +000051{
Denis Vlasenko1265df12009-01-13 15:22:50 +000052 if (!elm)
Denis Vlasenkoc115fdb2007-03-06 22:53:10 +000053 return;
Denis Vlasenko1265df12009-01-13 15:22:50 +000054 while (*head) {
55 if (*head == elm) {
56 *head = (*head)->link;
57 break;
Denis Vlasenkoc115fdb2007-03-06 22:53:10 +000058 }
Denis Vlasenko1265df12009-01-13 15:22:50 +000059 head = &(*head)->link;
Denis Vlasenkoc115fdb2007-03-06 22:53:10 +000060 }
61}
62
Rob Landleya6b5b602006-05-08 19:03:07 +000063/* Recursively free all elements in the linked list. If freeit != NULL
64 * call it on each datum in the list */
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +000065void FAST_FUNC llist_free(llist_t *elm, void (*freeit) (void *data))
Bernhard Reutner-Fischer56b21712005-10-06 12:10:48 +000066{
Rob Landleya6b5b602006-05-08 19:03:07 +000067 while (elm) {
68 void *data = llist_pop(&elm);
Bernhard Reutner-Fischerd909d232007-02-04 20:32:38 +000069
70 if (freeit)
71 freeit(data);
Rob Landleya6b5b602006-05-08 19:03:07 +000072 }
Bernhard Reutner-Fischer56b21712005-10-06 12:10:48 +000073}
Denis Vlasenkoc8400a22006-10-25 00:33:44 +000074
Denis Vlasenko8d9f4952007-04-08 15:08:42 +000075/* Reverse list order. */
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +000076llist_t* FAST_FUNC llist_rev(llist_t *list)
Denis Vlasenkoc8400a22006-10-25 00:33:44 +000077{
Denis Vlasenko8d9f4952007-04-08 15:08:42 +000078 llist_t *rev = NULL;
Bernhard Reutner-Fischerd909d232007-02-04 20:32:38 +000079
Denis Vlasenkoc8400a22006-10-25 00:33:44 +000080 while (list) {
81 llist_t *next = list->link;
Bernhard Reutner-Fischerd909d232007-02-04 20:32:38 +000082
Denis Vlasenko8d9f4952007-04-08 15:08:42 +000083 list->link = rev;
84 rev = list;
Denis Vlasenkoc8400a22006-10-25 00:33:44 +000085 list = next;
86 }
Denis Vlasenko8d9f4952007-04-08 15:08:42 +000087 return rev;
Denis Vlasenkoc8400a22006-10-25 00:33:44 +000088}
Denis Vlasenko0b791d92009-04-13 20:52:00 +000089
90llist_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}