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