aboutsummaryrefslogtreecommitdiff
path: root/libbb/llist.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbb/llist.c')
-rw-r--r--libbb/llist.c54
1 files changed, 41 insertions, 13 deletions
diff --git a/libbb/llist.c b/libbb/llist.c
index cb87176c5..ce7daddee 100644
--- a/libbb/llist.c
+++ b/libbb/llist.c
@@ -1,9 +1,18 @@
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 Fischer
8 *
9 * Licensed under the GPL v2, see the file LICENSE in this tarball.
10 */
1#include <stdlib.h> 11#include <stdlib.h>
2#include <string.h>
3#include "unarchive.h"
4#include "libbb.h" 12#include "libbb.h"
5 13
6#ifdef L_llist_add_to 14#ifdef L_llist_add_to
15/* Add data to the start of the linked list. */
7extern llist_t *llist_add_to(llist_t *old_head, char *new_item) 16extern llist_t *llist_add_to(llist_t *old_head, char *new_item)
8{ 17{
9 llist_t *new_head; 18 llist_t *new_head;
@@ -17,27 +26,46 @@ extern llist_t *llist_add_to(llist_t *old_head, char *new_item)
17#endif 26#endif
18 27
19#ifdef L_llist_add_to_end 28#ifdef L_llist_add_to_end
29/* Add data to the end of the linked list. */
20extern llist_t *llist_add_to_end(llist_t *list_head, char *data) 30extern llist_t *llist_add_to_end(llist_t *list_head, char *data)
21{ 31{
22 llist_t *new_item, *tmp, *prev; 32 llist_t *new_item;
23 33
24 new_item = xmalloc(sizeof(llist_t)); 34 new_item = xmalloc(sizeof(llist_t));
25 new_item->data = data; 35 new_item->data = data;
26 new_item->link = NULL; 36 new_item->link = NULL;
27 37
28 prev = NULL; 38 if (list_head == NULL) {
29 tmp = list_head;
30 while (tmp) {
31 prev = tmp;
32 tmp = tmp->link;
33 }
34 if (prev) {
35 prev->link = new_item;
36 } else {
37 list_head = new_item; 39 list_head = new_item;
40 } else {
41 llist_t *tail = list_head;
42 while (tail->link)
43 tail = tail->link;
44 tail->link = new_item;
38 } 45 }
46 return list_head;
47}
48#endif
39 49
40 return (list_head); 50#ifdef L_llist_free_one
51/* Free the current list element and advance to the next entry in the list.
52 * Returns a pointer to the next element. */
53extern llist_t *llist_free_one(llist_t *elm)
54{
55 llist_t *next = elm ? elm->link : NULL;
56#if ENABLE_DMALLOC /* avoid warnings from dmalloc's error-free-null option */
57 if (elm)
58#endif
59 free(elm);
60 elm = next;
61 return elm;
41} 62}
42#endif 63#endif
43 64
65#ifdef L_llist_free
66/* Recursively free all elements in the linked list. */
67extern void llist_free(llist_t *elm)
68{
69 while ((elm = llist_free_one(elm)));
70}
71#endif