]> the.earth.li Git - onak.git/blob - ll.c
70603b40cfd233bd4022d8a742bef500f0fc2580
[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 <assert.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23
24 #include "ll.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                 return NULL;
49         }
50
51         new->next = NULL;
52         new->object = object;
53
54         if (curll != NULL) {
55                 cur = curll;
56                 while (cur->next != NULL) {
57                         cur = cur->next;
58                 }
59                 cur->next = new;
60         } else {
61                 curll = new;
62         }
63         
64         return curll;
65 }
66
67 struct ll *lldel(struct ll *curll, void *object,
68         int (*objectcmp) (const void *object1, const void *object2))
69 {
70         struct ll *cur = NULL;
71         struct ll *old = NULL;
72
73         assert(objectcmp != NULL);
74
75         cur = curll;
76         if (cur == NULL) {
77                 return NULL;
78         } else if (!(*objectcmp)(cur->object, object)) {
79                 old = cur;
80                 cur = cur->next;
81                 free(old);
82                 return cur;
83         } 
84         while (cur->next != NULL) {
85                 if (!(*objectcmp)(cur->next->object, object)) {
86                         old = cur->next;
87                         cur->next = cur->next->next;
88                         free(old);
89                         break;
90                 }
91         }
92         return curll;
93 }
94
95 struct ll *llfind(struct ll *curll, void *object,
96         int (*objectcmp) (const void *object1, const void *object2))
97 {
98         struct ll *cur;
99
100         assert(objectcmp != NULL);
101
102         cur = curll;
103         while (cur != NULL && (*objectcmp)(cur->object, object)) {
104                 cur = cur->next;
105         }
106         return cur;
107 }
108
109 unsigned long llsize(struct ll *curll)
110 {
111         unsigned long count = 0;
112
113         while (curll != NULL) {
114                 count++;
115                 curll = curll->next;
116         }
117
118         return count;
119 }
120
121 void llfree(struct ll *curll, void (*objectfree) (void *object))
122 {
123         struct ll *nextll;
124
125         while (curll != NULL) {
126                 nextll = curll->next;
127                 if (curll->object != NULL && objectfree != NULL) {
128                         objectfree(curll->object);
129                         curll->object = NULL;
130                 }
131                 free(curll);
132                 curll = nextll;
133         }
134         return;
135 }