]> the.earth.li Git - onak.git/blob - ll.c
0.6.2 release
[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, see <https://www.gnu.org/licenses/>.
17  */
18
19 #include <assert.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22
23 #include "ll.h"
24
25 struct ll *lladd(struct ll *curll, void *object)
26 {
27         struct ll *new;
28
29         if ((new = malloc(sizeof(struct ll))) == NULL) {
30                 perror("lladd()");
31                 printf("Got NULL in lladd()\n");
32                 return NULL;
33         }
34
35         new->next = curll;
36         new->object = object;
37
38         return new;
39 }
40
41 struct ll *lladdend(struct ll *curll, void *object)
42 {
43         struct ll *new;
44         struct ll *cur;
45
46         if ((new = malloc(sizeof(struct ll))) == NULL) {
47                 return NULL;
48         }
49
50         new->next = NULL;
51         new->object = object;
52
53         if (curll != NULL) {
54                 cur = curll;
55                 while (cur->next != NULL) {
56                         cur = cur->next;
57                 }
58                 cur->next = new;
59         } else {
60                 curll = new;
61         }
62         
63         return curll;
64 }
65
66 struct ll *lldel(struct ll *curll, void *object,
67         int (*objectcmp) (const void *object1, const void *object2))
68 {
69         struct ll *cur = NULL;
70         struct ll *old = NULL;
71
72         assert(objectcmp != NULL);
73
74         cur = curll;
75         if (cur == NULL) {
76                 return NULL;
77         } else if (!(*objectcmp)(cur->object, object)) {
78                 old = cur;
79                 cur = cur->next;
80                 free(old);
81                 return cur;
82         } 
83         while (cur->next != NULL) {
84                 if (!(*objectcmp)(cur->next->object, object)) {
85                         old = cur->next;
86                         cur->next = cur->next->next;
87                         free(old);
88                         break;
89                 }
90         }
91         return curll;
92 }
93
94 struct ll *llfind(struct ll *curll, void *object,
95         int (*objectcmp) (const void *object1, const void *object2))
96 {
97         struct ll *cur;
98
99         assert(objectcmp != NULL);
100
101         cur = curll;
102         while (cur != NULL && (*objectcmp)(cur->object, object)) {
103                 cur = cur->next;
104         }
105         return cur;
106 }
107
108 unsigned long llsize(struct ll *curll)
109 {
110         unsigned long count = 0;
111
112         while (curll != NULL) {
113                 count++;
114                 curll = curll->next;
115         }
116
117         return count;
118 }
119
120 void llfree(struct ll *curll, void (*objectfree) (void *object))
121 {
122         struct ll *nextll;
123
124         while (curll != NULL) {
125                 nextll = curll->next;
126                 if (curll->object != NULL && objectfree != NULL) {
127                         objectfree(curll->object);
128                         curll->object = NULL;
129                 }
130                 free(curll);
131                 curll = nextll;
132         }
133         return;
134 }