]> git.sommitrealweird.co.uk Git - onak.git/blob - ll.c
ed6315a4e2048b1a5d0b8ec56f79a96218e380b6
[onak.git] / ll.c
1 /*
2  * ll.c - various things of used for dealing with linked lists.
3  *
4  * Copyright 2000-2004 Jonathan McDowell <noodles@earth.li>
5  *
6  * This program is free software: you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the Free
8  * Software Foundation; version 2 of the License.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * this program; if not, write to the Free Software Foundation, Inc., 51
17  * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22
23 #include "ll.h"
24 #include "log.h"
25
26 struct ll *lladd(struct ll *curll, void *object)
27 {
28         struct ll *new;
29
30         if ((new = malloc(sizeof(struct ll))) == NULL) {
31                 perror("lladd()");
32                 printf("Got NULL in lladd()\n");
33                 return NULL;
34         }
35
36         new->next = curll;
37         new->object = object;
38
39         return new;
40 }
41
42 struct ll *lladdend(struct ll *curll, void *object)
43 {
44         struct ll *new;
45         struct ll *cur;
46
47         if ((new = malloc(sizeof(struct ll))) == NULL) {
48                 logthing(LOGTHING_ERROR,
49                                 "Couldn't allocate memory in lladdend()");
50                 return NULL;
51         }
52
53         new->next = NULL;
54         new->object = object;
55
56         if (curll != NULL) {
57                 cur = curll;
58                 while (cur->next != NULL) {
59                         cur = cur->next;
60                 }
61                 cur->next = new;
62         } else {
63                 curll = new;
64         }
65         
66         return curll;
67 }
68
69 struct ll *lldel(struct ll *curll, void *object,
70         int (*objectcmp) (const void *object1, const void *object2))
71 {
72         struct ll *cur = NULL;
73         struct ll *old = NULL;
74
75         log_assert(objectcmp != NULL);
76
77         cur = curll;
78         if (cur == NULL) {
79                 return NULL;
80         } else if (!(*objectcmp)(cur->object, object)) {
81                 old = cur;
82                 cur = cur->next;
83                 free(old);
84                 return cur;
85         } 
86         while (cur->next != NULL) {
87                 if (!(*objectcmp)(cur->next->object, object)) {
88                         old = cur->next;
89                         cur->next = cur->next->next;
90                         free(old);
91                         break;
92                 }
93         }
94         return curll;
95 }
96
97 struct ll *llfind(struct ll *curll, void *object,
98         int (*objectcmp) (const void *object1, const void *object2))
99 {
100         struct ll *cur;
101
102         log_assert(objectcmp != NULL);
103
104         cur = curll;
105         while (cur != NULL && (*objectcmp)(cur->object, object)) {
106                 cur = cur->next;
107         }
108         return cur;
109 }
110
111 unsigned long llsize(struct ll *curll)
112 {
113         unsigned long count = 0;
114
115         while (curll != NULL) {
116                 count++;
117                 curll = curll->next;
118         }
119
120         return count;
121 }
122
123 /**
124  *      llfree - Frees a linked list.
125  *      @curll: The list to free.
126  *      @objectfree: A pointer to a free function for the object.
127  *
128  *      Walks through a list and free it. If a function is provided for
129  *      objectfree then it's called for each element to free them, if it's NULL
130  *      just the list is freed.
131  */
132 void llfree(struct ll *curll, void (*objectfree) (void *object))
133 {
134         struct ll *nextll;
135
136         while (curll != NULL) {
137                 nextll = curll->next;
138                 if (curll->object != NULL && objectfree != NULL) {
139                         objectfree(curll->object);
140                         curll->object = NULL;
141                 }
142                 free(curll);
143                 curll = nextll;
144         }
145         return;
146 }