blob: e964a9b723bc55e2348706942e11fb527a1f164b [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 *
Denys Vlasenko0ef64bd2010-08-16 20:14:46 +020010 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
Bernhard Reutner-Fischer56b21712005-10-06 12:10:48 +000011 */
Bernhard Reutner-Fischerbee9eb12005-09-29 12:55:10 +000012#include "libbb.h"
13
Bernhard Reutner-Fischer56b21712005-10-06 12:10:48 +000014/* Add data to the start of the linked list. */
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +000015void FAST_FUNC llist_add_to(llist_t **old_head, void *data)
Bernhard Reutner-Fischerbee9eb12005-09-29 12:55:10 +000016{
Rob Landley8bb50782006-05-26 23:44:51 +000017 llist_t *new_head = xmalloc(sizeof(llist_t));
Bernhard Reutner-Fischerd909d232007-02-04 20:32:38 +000018
Rob Landley5edc1022006-05-26 23:00:10 +000019 new_head->data = data;
Rob Landley8bb50782006-05-26 23:44:51 +000020 new_head->link = *old_head;
21 *old_head = new_head;
Bernhard Reutner-Fischerbee9eb12005-09-29 12:55:10 +000022}
Bernhard Reutner-Fischerbee9eb12005-09-29 12:55:10 +000023
Bernhard Reutner-Fischer56b21712005-10-06 12:10:48 +000024/* Add data to the end of the linked list. */
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +000025void FAST_FUNC llist_add_to_end(llist_t **list_head, void *data)
Bernhard Reutner-Fischerbee9eb12005-09-29 12:55:10 +000026{
Denis Vlasenko1265df12009-01-13 15:22:50 +000027 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;*/
Bernhard Reutner-Fischerbee9eb12005-09-29 12:55:10 +000032}
Bernhard Reutner-Fischerbee9eb12005-09-29 12:55:10 +000033
Rob Landleya6b5b602006-05-08 19:03:07 +000034/* Remove first element from the list and return it */
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +000035void* FAST_FUNC llist_pop(llist_t **head)
Bernhard Reutner-Fischer56b21712005-10-06 12:10:48 +000036{
Denis Vlasenko1265df12009-01-13 15:22:50 +000037 void *data = NULL;
38 llist_t *temp = *head;
Rob Landleya6b5b602006-05-08 19:03:07 +000039
Denis Vlasenko1265df12009-01-13 15:22:50 +000040 if (temp) {
41 data = temp->data;
42 *head = temp->link;
43 free(temp);
44 }
Rob Landleya6b5b602006-05-08 19:03:07 +000045 return data;
Bernhard Reutner-Fischer56b21712005-10-06 12:10:48 +000046}
Bernhard Reutner-Fischer56b21712005-10-06 12:10:48 +000047
Denis Vlasenkoc115fdb2007-03-06 22:53:10 +000048/* Unlink arbitrary given element from the list */
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +000049void FAST_FUNC llist_unlink(llist_t **head, llist_t *elm)
Denis Vlasenkoc115fdb2007-03-06 22:53:10 +000050{
Denis Vlasenko1265df12009-01-13 15:22:50 +000051 if (!elm)
Denis Vlasenkoc115fdb2007-03-06 22:53:10 +000052 return;
Denis Vlasenko1265df12009-01-13 15:22:50 +000053 while (*head) {
54 if (*head == elm) {
55 *head = (*head)->link;
56 break;
Denis Vlasenkoc115fdb2007-03-06 22:53:10 +000057 }
Denis Vlasenko1265df12009-01-13 15:22:50 +000058 head = &(*head)->link;
Denis Vlasenkoc115fdb2007-03-06 22:53:10 +000059 }
60}
61
Rob Landleya6b5b602006-05-08 19:03:07 +000062/* Recursively free all elements in the linked list. If freeit != NULL
63 * call it on each datum in the list */
Denys Vlasenko9be47022011-05-16 12:21:31 +020064void FAST_FUNC llist_free(llist_t *elm, void (*freeit)(void *data))
Bernhard Reutner-Fischer56b21712005-10-06 12:10:48 +000065{
Rob Landleya6b5b602006-05-08 19:03:07 +000066 while (elm) {
67 void *data = llist_pop(&elm);
Bernhard Reutner-Fischerd909d232007-02-04 20:32:38 +000068
69 if (freeit)
70 freeit(data);
Rob Landleya6b5b602006-05-08 19:03:07 +000071 }
Bernhard Reutner-Fischer56b21712005-10-06 12:10:48 +000072}
Denis Vlasenkoc8400a22006-10-25 00:33:44 +000073
Denis Vlasenko8d9f4952007-04-08 15:08:42 +000074/* Reverse list order. */
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +000075llist_t* FAST_FUNC llist_rev(llist_t *list)
Denis Vlasenkoc8400a22006-10-25 00:33:44 +000076{
Denis Vlasenko8d9f4952007-04-08 15:08:42 +000077 llist_t *rev = NULL;
Bernhard Reutner-Fischerd909d232007-02-04 20:32:38 +000078
Denis Vlasenkoc8400a22006-10-25 00:33:44 +000079 while (list) {
80 llist_t *next = list->link;
Bernhard Reutner-Fischerd909d232007-02-04 20:32:38 +000081
Denis Vlasenko8d9f4952007-04-08 15:08:42 +000082 list->link = rev;
83 rev = list;
Denis Vlasenkoc8400a22006-10-25 00:33:44 +000084 list = next;
85 }
Denis Vlasenko8d9f4952007-04-08 15:08:42 +000086 return rev;
Denis Vlasenkoc8400a22006-10-25 00:33:44 +000087}
Denis Vlasenko0b791d92009-04-13 20:52:00 +000088
89llist_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}