]> git.sommitrealweird.co.uk Git - onak.git/blob - ll.c
Give Brett some credit.
[onak.git] / ll.c
1 /*
2  * ll.c - various things of used for dealing with linked lists.
3  *
4  * Jonathan McDowell <noodles@earth.li>
5  *
6  * Copyright 2000-2002 Project Purple
7  */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11
12 #include "ll.h"
13 #include "log.h"
14
15 struct ll *lladd(struct ll *curll, void *object)
16 {
17         struct ll *new;
18
19         if ((new = malloc(sizeof(struct ll))) == NULL) {
20                 perror("lladd()");
21                 printf("Got NULL in lladd()\n");
22                 return NULL;
23         }
24
25         new->next = curll;
26         new->object = object;
27
28         return new;
29 }
30
31 struct ll *lladdend(struct ll *curll, void *object)
32 {
33         struct ll *new;
34         struct ll *cur;
35
36         if ((new = malloc(sizeof(struct ll))) == NULL) {
37                 logthing(LOGTHING_ERROR,
38                                 "Couldn't allocate memory in lladdend()");
39                 return NULL;
40         }
41
42         new->next = NULL;
43         new->object = object;
44
45         if (curll != NULL) {
46                 cur = curll;
47                 while (cur->next != NULL) {
48                         cur = cur->next;
49                 }
50                 cur->next = new;
51         } else {
52                 curll = new;
53         }
54         
55         return curll;
56 }
57
58 struct ll *lldel(struct ll *curll, void *object,
59         int (*objectcmp) (const void *object1, const void *object2))
60 {
61         struct ll *cur = NULL;
62         struct ll *old = NULL;
63
64         log_assert(objectcmp != NULL);
65
66         cur = curll;
67         if (cur == NULL) {
68                 return NULL;
69         } else if (!(*objectcmp)(cur->object, object)) {
70                 old = cur;
71                 cur = cur->next;
72                 free(old);
73                 return cur;
74         } 
75         while (cur->next != NULL) {
76                 if (!(*objectcmp)(cur->next->object, object)) {
77                         old = cur->next;
78                         cur->next = cur->next->next;
79                         free(old);
80                         break;
81                 }
82         }
83         return curll;
84 }
85
86 struct ll *llfind(struct ll *curll, void *object,
87         int (*objectcmp) (const void *object1, const void *object2))
88 {
89         struct ll *cur;
90
91         log_assert(objectcmp != NULL);
92
93         cur = curll;
94         while (cur != NULL && (*objectcmp)(cur->object, object)) {
95                 cur = cur->next;
96         }
97         return cur;
98 }
99
100 unsigned long llsize(struct ll *curll)
101 {
102         unsigned long count = 0;
103
104         while (curll != NULL) {
105                 count++;
106                 curll = curll->next;
107         }
108
109         return count;
110 }
111
112 /**
113  *      llfree - Frees a linked list.
114  *      @curll: The list to free.
115  *      @objectfree: A pointer to a free function for the object.
116  *
117  *      Walks through a list and free it. If a function is provided for
118  *      objectfree then it's called for each element to free them, if it's NULL
119  *      just the list is freed.
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 }