summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile8
-rw-r--r--src/ll.c166
-rw-r--r--src/ll.h36
3 files changed, 154 insertions, 56 deletions
diff --git a/src/Makefile b/src/Makefile
index 4a0d316..d12eb72 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -20,11 +20,11 @@ BINARIES := main encryption
20 20
21all: main 21all: main
22 22
23main: main.o shared.o 23main: main.o shared.o ll.o arena.o
24 24
25ll.o: ll.c ll.h 25ll.o: ll.c ll.h shared.h
26main.o: main.c 26main.o: main.c shared.h
27arena.o: arena.c arena.h 27arena.o: arena.c arena.h shared.h
28shared.o: shared.c shared.h 28shared.o: shared.c shared.h
29 29
30encryption: encryption.c encryption.h shared.o shared.h 30encryption: encryption.c encryption.h shared.o shared.h
diff --git a/src/ll.c b/src/ll.c
index b42f631..ae62e89 100644
--- a/src/ll.c
+++ b/src/ll.c
@@ -3,6 +3,49 @@
3 3
4#include <stddef.h> 4#include <stddef.h>
5#include <stdlib.h> 5#include <stdlib.h>
6#include <errno.h>
7
8typedef struct dll {
9 void *data;
10 dlinkedlist_freecallback dfreecb;
11
12 struct dll *next;
13 struct dll *prev;
14} dllnode;
15
16typedef struct dlinkedlist {
17 dllnode *start;
18 dllnode *end;
19 size_t size;
20} dlinkedlist;
21
22dllnode* dllnode_init(void *data, dlinkedlist_freecallback dfreecb) {
23 dllnode *n = xcalloc(1, sizeof(*n));
24 n->next = NULL;
25 n->prev = NULL;
26 n->data = data;
27 n->dfreecb = dfreecb;
28
29 return n;
30}
31
32int dllnode_free(dllnode **n) {
33 if(!n) {
34 errno = EINVAL;
35 return -1;
36 }
37 if(!(*n)) {
38 errno = EINVAL;
39 return -1;
40 }
41
42 if((*n)->dfreecb != NULL)
43 (*n)->dfreecb((*n)->data);
44 free(*n);
45 *n = NULL;
46
47 return 0;
48}
6 49
7void dlinkedlist_init(dlinkedlist **ll) { 50void dlinkedlist_init(dlinkedlist **ll) {
8 (*ll) = xcalloc(1, sizeof(**ll)); 51 (*ll) = xcalloc(1, sizeof(**ll));
@@ -18,11 +61,7 @@ void dlinkedlist_free(dlinkedlist **ll) {
18 dllnode *p = (*ll)->start, *n; 61 dllnode *p = (*ll)->start, *n;
19 while(p != NULL) { 62 while(p != NULL) {
20 n = p->next; 63 n = p->next;
21 64 dllnode_free(&p);
22 if(p->dfreecb != NULL)
23 p->dfreecb(p->data);
24 free(p);
25
26 p = n; 65 p = n;
27 } 66 }
28 67
@@ -31,17 +70,15 @@ void dlinkedlist_free(dlinkedlist **ll) {
31 return; 70 return;
32} 71}
33 72
34int dlinkedlist_firstitem(dlinkedlist * const ll, void *data, int (*dfreecb)(void*)) { 73int dlinkedlist_firstitem(dlinkedlist * const ll, void *data, dlinkedlist_freecallback dfreecb) {
35 if(!ll) 74 if(!ll) {
75 errno = EINVAL;
36 return -1; 76 return -1;
77 }
37 if(ll->size != 0) 78 if(ll->size != 0)
38 return 0; 79 return 0;
39 80
40 dllnode *n = xcalloc(1, sizeof(*n)); 81 dllnode *n = dllnode_init(data, dfreecb);
41 n->next = NULL;
42 n->prev = NULL;
43 n->data = data;
44 n->dfreecb = dfreecb;
45 82
46 ll->start = n; 83 ll->start = n;
47 ll->end = n; 84 ll->end = n;
@@ -50,15 +87,15 @@ int dlinkedlist_firstitem(dlinkedlist * const ll, void *data, int (*dfreecb)(voi
50 return 1; 87 return 1;
51} 88}
52 89
53int dlinkedlist_insert(dlinkedlist * const ll, void *data, int (*dfreecb)(void*)) { 90int dlinkedlist_insert(dlinkedlist * const ll, void *data, dlinkedlist_freecallback dfreecb) {
54 if(!ll) 91 if(!ll) {
92 errno = EINVAL;
55 return -1; 93 return -1;
94 }
56 if(dlinkedlist_firstitem(ll, data, dfreecb) > 0) 95 if(dlinkedlist_firstitem(ll, data, dfreecb) > 0)
57 return 0; 96 return 0;
58 97
59 dllnode *n = xcalloc(1, sizeof(*n)); 98 dllnode *n = dllnode_init(data, dfreecb);
60 n->data = data;
61 n->dfreecb = dfreecb;
62 n->prev = NULL; 99 n->prev = NULL;
63 n->next = ll->start; 100 n->next = ll->start;
64 101
@@ -69,15 +106,15 @@ int dlinkedlist_insert(dlinkedlist * const ll, void *data, int (*dfreecb)(void*)
69 return 0; 106 return 0;
70} 107}
71 108
72int dlinkedlist_append(dlinkedlist * const ll, void *data, int (*dfreecb)(void*)) { 109int dlinkedlist_append(dlinkedlist * const ll, void *data, dlinkedlist_freecallback dfreecb) {
73 if(!ll) 110 if(!ll) {
111 errno = EINVAL;
74 return -1; 112 return -1;
113 }
75 if(dlinkedlist_firstitem(ll, data, dfreecb) > 0) 114 if(dlinkedlist_firstitem(ll, data, dfreecb) > 0)
76 return 0; 115 return 0;
77 116
78 dllnode *n = xcalloc(1, sizeof(*n)); 117 dllnode *n = dllnode_init(data, dfreecb);
79 n->data = data;
80 n->dfreecb = dfreecb;
81 n->prev = ll->end; 118 n->prev = ll->end;
82 n->next = NULL; 119 n->next = NULL;
83 120
@@ -88,12 +125,89 @@ int dlinkedlist_append(dlinkedlist * const ll, void *data, int (*dfreecb)(void*)
88 return 0; 125 return 0;
89} 126}
90 127
91dllnode *dlinkedlist_get(const dlinkedlist * const ll, size_t index) { 128dllnode *dlinkedlist_getnode(const dlinkedlist * const ll, size_t index) {
92 if(index >= ll->size) 129 if(!ll) {
130 errno = EINVAL;
93 return NULL; 131 return NULL;
132 }
133 if(index >= ll->size) {
134 errno = EINVAL;
135 return NULL;
136 }
137
138 // No need to loop if the desired indices are either the first or last
139 if(index == 0)
140 return ll->start->data;
141 if(index == (ll->size - 1))
142 return ll->end->data;
94 143
95 dllnode *p = ll->start; 144 int spoint = (index < (ll->size / 2));
96 for(size_t i = 0; i < index && p != NULL; i++, p = p->next); 145 dllnode *p = (spoint) ? ll->start : ll->end;
146 size_t i = (spoint) ? 0 : ll->size-1;
147
148 // This should (theoretically) cut down on fetch times
149 for(; ((spoint) ? (i < index) : (i > index)) && p != NULL; ((spoint) ? i++ : i--), p = ((spoint) ? p->next : p->prev));
150
151 // old imp (above is untested)
152 // for(size_t i = 0; i < index && p != NULL; i++, p = p->next);
97 153
98 return p; 154 return p;
155}
156
157void *dlinkedlist_get(const dlinkedlist * const ll, size_t index) {
158 dllnode *n = dlinkedlist_getnode(ll, index);
159 if(!n)
160 return NULL;
161
162 return n->data;
163}
164
165void *dlinkedlist_getfirst(const dlinkedlist * const ll) {
166 return dlinkedlist_get(ll, 0);
167}
168
169void *dlinkedlist_getlast(const dlinkedlist * const ll) {
170 return dlinkedlist_get(ll, ll->size - 1);
171}
172
173int dlinkedlist_remove(dlinkedlist * const ll, size_t index) {
174 if(!ll) {
175 errno = EINVAL;
176 return -1;
177 }
178 if(index >= ll->size) {
179 errno = EINVAL;
180 return -1;
181 }
182
183 dllnode *current = dlinkedlist_getnode(ll, index);
184 if(!current) {
185 /* gcc is halucinating an error where there isn't one, claiming that the size of the linked list could, somehow, magically
186 // grow in the time it takes to grab the desired node, and thus return NULL and cause a NULL Dereference. I am willing to
187 // be humble and state that the compiler is probably smarter than me, and there is MAYBE an edge case where is COULD occur,
188 // and thus I should do this check, but I'm unconvinced */
189 errno = ENOTRECOVERABLE;
190 return -2;
191 }
192
193 // Handle special cases of removing the start or end
194 if(index == 0) {
195 ll->start = current->next;
196 ll->start->prev = NULL;
197 } else if(index == (ll->size - 1)) {
198 ll->end = current->prev;
199 ll->end->next = NULL;
200 } else {
201 // Set the prior's next to the next, set the next's prior to the prior, delete the current one
202 dllnode *prev = current->prev;
203 dllnode *next = current->next;
204 prev->next = next;
205 next->prev = prev;
206 }
207 // Wow, I genuinely can't think of the last time I've needed to use an if-elif-else block
208
209 dllnode_free(&current);
210 ll->size--;
211
212 return 0;
99} \ No newline at end of file 213} \ No newline at end of file
diff --git a/src/ll.h b/src/ll.h
index 5e47bd9..f5846fb 100644
--- a/src/ll.h
+++ b/src/ll.h
@@ -1,35 +1,19 @@
1#ifndef __VXGG_REWRITE___SHARED_H___28542989122405___ 1#ifndef __VXGG_REWRITE___LL_H___305861098005___
2#define __VXGG_REWRITE___SHARED_H___28542989122405___ 2#define __VXGG_REWRITE___LL_H___305861098005___
3 3
4#include <stddef.h> 4#include <stddef.h>
5 5
6typedef struct dll { 6typedef int (*dlinkedlist_freecallback)(void*);
7 void *data; 7typedef struct dlinkedlist dlinkedlist;
8 int (*dfreecb)(void*);
9 8
10 struct dll *next;
11 struct dll *prev;
12} dllnode;
13
14typedef struct {
15 dllnode *start;
16 dllnode *end;
17 size_t size;
18} dlinkedlist;
19
20// Initialize a dlinkedlist
21void dlinkedlist_init(dlinkedlist **ll); 9void dlinkedlist_init(dlinkedlist **ll);
22
23// Free a dlinkedlist and its elements
24void dlinkedlist_free(dlinkedlist **ll); 10void dlinkedlist_free(dlinkedlist **ll);
25 11
26// Insert an element to the beginning of the list 12int dlinkedlist_insert(dlinkedlist * const ll, void *data, dlinkedlist_freecallback dfreecb);
27int dlinkedlist_insert(dlinkedlist * const ll, void *data, int (*dfreecb)(void*)); 13int dlinkedlist_append(dlinkedlist * const ll, void *data, dlinkedlist_freecallback dfreecb);
28 14void *dlinkedlist_get(const dlinkedlist * const ll, size_t index);
29// Insert an element to the end of the list 15void *dlinkedlist_getfirst(const dlinkedlist * const ll);
30int dlinkedlist_append(dlinkedlist * const ll, void *data, int (*dfreecb)(void*)); 16void *dlinkedlist_getlast(const dlinkedlist * const ll);
31 17int dlinkedlist_remove(dlinkedlist * const ll, size_t index);
32// Get the element from a dlinkedlist at index
33dllnode *dlinkedlist_get(const dlinkedlist * const ll, size_t index);
34 18
35#endif \ No newline at end of file 19#endif \ No newline at end of file