diff options
Diffstat (limited to 'libbb/llist.c')
-rw-r--r-- | libbb/llist.c | 54 |
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. */ | ||
7 | extern llist_t *llist_add_to(llist_t *old_head, char *new_item) | 16 | extern 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. */ | ||
20 | extern llist_t *llist_add_to_end(llist_t *list_head, char *data) | 30 | extern 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. */ | ||
53 | extern 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. */ | ||
67 | extern void llist_free(llist_t *elm) | ||
68 | { | ||
69 | while ((elm = llist_free_one(elm))); | ||
70 | } | ||
71 | #endif | ||