summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libcnary/CMakeLists.txt16
-rw-r--r--libcnary/Makefile21
-rw-r--r--libcnary/README5
-rw-r--r--libcnary/cnary.c30
-rw-r--r--libcnary/include/iterator.h33
-rw-r--r--libcnary/include/list.h24
-rw-r--r--libcnary/include/node.h59
-rw-r--r--libcnary/include/node_iterator.h39
-rw-r--r--libcnary/include/node_list.h31
-rw-r--r--libcnary/include/object.h25
-rw-r--r--libcnary/iterator.c45
-rw-r--r--libcnary/list.c31
-rw-r--r--libcnary/node.c207
-rw-r--r--libcnary/node_iterator.c64
-rw-r--r--libcnary/node_list.c130
15 files changed, 760 insertions, 0 deletions
diff --git a/libcnary/CMakeLists.txt b/libcnary/CMakeLists.txt
new file mode 100644
index 0000000..bbbe8ce
--- /dev/null
+++ b/libcnary/CMakeLists.txt
@@ -0,0 +1,16 @@
1cmake_minimum_required(VERSION 2.6)
2
3SET(libcnary_SRC
4 iterator.c
5 list.c
6 node.c
7 node_iterator.c
8 node_list.c )
9
10INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include)
11
12SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
13ADD_LIBRARY(libcnary STATIC ${libcnary_SRC})
14
15SET_TARGET_PROPERTIES(libcnary PROPERTIES OUTPUT_NAME cnary)
16
diff --git a/libcnary/Makefile b/libcnary/Makefile
new file mode 100644
index 0000000..bdd165d
--- /dev/null
+++ b/libcnary/Makefile
@@ -0,0 +1,21 @@
1TARGET = cnary
2LIBRARY = libcnary.a
3OBJECTS = cnary.o libcnary.a
4LIBRARY_OBJECTS = node.o list.o iterator.o node_list.o node_iterator.o
5CFLAGS=-g -I./include -I/opt/local/include -mmacosx-version-min=10.5 -arch i386 -isysroot /Developer/SDKs/MacOSX10.5.sdk
6LDFLAGS=-L/opt/local/lib -framework CoreFoundation -mmacosx-version-min=10.5 -arch i386 -isysroot /Developer/SDKs/MacOSX10.5.sdk -Wl,-no_compact_linkedit
7
8
9%.o: %.c
10 $(CC) -o $(@) -c $(^) $(CFLAGS)
11
12$(LIBRARY): $(LIBRARY_OBJECTS)
13 $(AR) rs $(@) $(^)
14
15$(TARGET): $(OBJECTS)
16 $(CC) -o $(@) $(^) $(CFLAGS) $(LDFLAGS)
17
18all: $(TARGET)
19
20clean:
21 rm -rf $(TARGET) $(LIBRARY) $(OBJECTS) $(LIBRARY_OBJECTS) \ No newline at end of file
diff --git a/libcnary/README b/libcnary/README
new file mode 100644
index 0000000..5472b4e
--- /dev/null
+++ b/libcnary/README
@@ -0,0 +1,5 @@
1Project Name:
2 libcnary
3
4Project Description:
5 A small N-ary (Tree) library written in C. \ No newline at end of file
diff --git a/libcnary/cnary.c b/libcnary/cnary.c
new file mode 100644
index 0000000..3e55fce
--- /dev/null
+++ b/libcnary/cnary.c
@@ -0,0 +1,30 @@
1/*
2 * cnary.c
3 *
4 * Created on: Mar 9, 2011
5 * Author: posixninja
6 */
7
8#include <stdio.h>
9
10#include "node.h"
11
12int main(int argc, char* argv[]) {
13 puts("Creating root node");
14 node_t* root = node_create(NULL, NULL);
15
16 puts("Creating child 1 node");
17 node_t* one = node_create(root, NULL);
18 puts("Creating child 2 node");
19 node_t* two = node_create(root, NULL);
20
21 puts("Creating child 3 node");
22 node_t* three = node_create(one, NULL);
23
24 puts("Debugging root node");
25 node_debug(root);
26
27 puts("Destroying root node");
28 node_destroy(root);
29 return 0;
30}
diff --git a/libcnary/include/iterator.h b/libcnary/include/iterator.h
new file mode 100644
index 0000000..debc1c5
--- /dev/null
+++ b/libcnary/include/iterator.h
@@ -0,0 +1,33 @@
1/*
2 * iterator.h
3 *
4 * Created on: Mar 8, 2011
5 * Author: posixninja
6 */
7
8#ifndef ITERATOR_H_
9#define ITERATOR_H_
10
11struct list_t;
12struct object_t;
13
14typedef struct iterator_t {
15 struct object_t*(*next)(struct iterator_t* iterator);
16 int(*bind)(struct iterator_t* iterator, struct list_t* list);
17
18 unsigned int count;
19 unsigned int position;
20
21 struct list_t* list;
22 struct object_t* end;
23 struct object_t* begin;
24 struct object_t* value;
25} iterator_t;
26
27void iterator_destroy(struct iterator_t* iterator);
28struct iterator_t* iterator_create(struct list_t* list);
29
30struct object_t* iterator_next(struct iterator_t* iterator);
31int iterator_bind(struct iterator_t* iterator, struct list_t* list);
32
33#endif /* ITERATOR_H_ */
diff --git a/libcnary/include/list.h b/libcnary/include/list.h
new file mode 100644
index 0000000..237aba0
--- /dev/null
+++ b/libcnary/include/list.h
@@ -0,0 +1,24 @@
1/*
2 * list.h
3 *
4 * Created on: Mar 8, 2011
5 * Author: posixninja
6 */
7
8#ifndef LIST_H_
9#define LIST_H_
10
11#include "object.h"
12
13typedef struct list_t {
14 void* next;
15 void* prev;
16} list_t;
17
18void list_init(struct list_t* list);
19void list_destroy(struct list_t* list);
20
21int list_add(struct list_t* list, struct object_t* object);
22int list_remove(struct list_t* list, struct object_t* object);
23
24#endif /* LIST_H_ */
diff --git a/libcnary/include/node.h b/libcnary/include/node.h
new file mode 100644
index 0000000..35f6333
--- /dev/null
+++ b/libcnary/include/node.h
@@ -0,0 +1,59 @@
1/*
2 * node.h
3 *
4 * Created on: Mar 7, 2011
5 * Author: posixninja
6 */
7
8#ifndef NODE_H_
9#define NODE_H_
10
11#include "object.h"
12
13#define NODE_TYPE 1;
14
15struct node_list_t;
16
17// This class implements the abstract iterator class
18typedef struct node_t {
19 // Super class
20 struct node_t* next;
21 struct node_t* prev;
22 unsigned int count;
23
24 // Local Properties
25 int isRoot;
26 int isLeaf;
27
28 // Local Members
29 void *data;
30 unsigned int depth;
31 struct node_t* parent;
32 struct node_list_t* children;
33
34 // Virtual Functions
35 int(*attach)(struct node_t* parent, struct node_t* child);
36 int(*detach)(struct node_t* parent, struct node_t* child);
37
38} node_t;
39
40void node_destroy(struct node_t* node);
41struct node_t* node_create(struct node_t* parent, void* data);
42
43int node_attach(struct node_t* parent, struct node_t* child);
44int node_detach(struct node_t* parent, struct node_t* child);
45int node_insert(struct node_t* parent, unsigned int index, struct node_t* child);
46
47unsigned int node_n_children(struct node_t* node);
48node_t* node_nth_child(struct node_t* node, unsigned int n);
49node_t* node_first_child(struct node_t* node);
50node_t* node_prev_sibling(struct node_t* node);
51node_t* node_next_sibling(struct node_t* node);
52int node_child_position(struct node_t* parent, node_t* child);
53
54typedef void* (*copy_func_t)(const void *src);
55node_t* node_copy_deep(node_t* node, copy_func_t copy_func);
56
57void node_debug(struct node_t* node);
58
59#endif /* NODE_H_ */
diff --git a/libcnary/include/node_iterator.h b/libcnary/include/node_iterator.h
new file mode 100644
index 0000000..8f39ceb
--- /dev/null
+++ b/libcnary/include/node_iterator.h
@@ -0,0 +1,39 @@
1/*
2 * node_iterator.h
3 *
4 * Created on: Mar 8, 2011
5 * Author: posixninja
6 */
7
8#ifndef NODE_ITERATOR_H_
9#define NODE_ITERATOR_H_
10
11#include "iterator.h"
12#include "node_list.h"
13
14// This class implements the abstract iterator class
15typedef struct node_iterator_t {
16 // Super class
17 struct iterator_t super;
18
19 // Local members
20 struct node_t*(*next)(struct node_iterator_t* iterator);
21 int(*bind)(struct node_iterator_t* iterator, struct node_list_t* list);
22
23 unsigned int count;
24 unsigned int position;
25
26 struct node_list_t* list;
27 struct node_t* end;
28 struct node_t* begin;
29 struct node_t* value;
30
31} node_iterator_t;
32
33void node_iterator_destroy(node_iterator_t* iterator);
34node_iterator_t* node_iterator_create(node_list_t* list);
35
36struct node_t* node_iterator_next(struct node_iterator_t* iterator);
37int node_iterator_bind(struct node_iterator_t* iterator, struct node_list_t* list);
38
39#endif /* NODE_ITERATOR_H_ */
diff --git a/libcnary/include/node_list.h b/libcnary/include/node_list.h
new file mode 100644
index 0000000..bb9fcae
--- /dev/null
+++ b/libcnary/include/node_list.h
@@ -0,0 +1,31 @@
1/*
2 * node_list.h
3 *
4 * Created on: Mar 8, 2011
5 * Author: posixninja
6 */
7
8#ifndef NODE_LIST_H_
9#define NODE_LIST_H_
10
11struct node_t;
12
13// This class implements the list_t abstract class
14typedef struct node_list_t {
15 // list_t members
16 struct node_t* begin;
17 struct node_t* end;
18
19 // node_list_t members
20 unsigned int count;
21
22} node_list_t;
23
24void node_list_destroy(struct node_list_t* list);
25struct node_list_t* node_list_create(struct node_t* node);
26
27int node_list_add(node_list_t* list, node_t* node);
28int node_list_insert(node_list_t* list, unsigned int index, node_t* node);
29int node_list_remove(node_list_t* list, node_t* node);
30
31#endif /* NODE_LIST_H_ */
diff --git a/libcnary/include/object.h b/libcnary/include/object.h
new file mode 100644
index 0000000..adf1891
--- /dev/null
+++ b/libcnary/include/object.h
@@ -0,0 +1,25 @@
1/*
2 * object.h
3 *
4 * Created on: Mar 8, 2011
5 * Author: posixninja
6 */
7
8#ifndef OBJECT_H_
9#define OBJECT_H_
10
11#ifndef TRUE
12#define TRUE 1
13#endif
14
15#ifndef FALSE
16#define FALSE 0
17#endif
18
19typedef struct object_t {
20 void* value;
21 unsigned int type;
22 unsigned int size;
23} object_t;
24
25#endif /* OBJECT_H_ */
diff --git a/libcnary/iterator.c b/libcnary/iterator.c
new file mode 100644
index 0000000..f4897f9
--- /dev/null
+++ b/libcnary/iterator.c
@@ -0,0 +1,45 @@
1/*
2 * iterator.c
3 *
4 * Created on: Mar 8, 2011
5 * Author: posixninja
6 */
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11
12#include "list.h"
13#include "object.h"
14#include "iterator.h"
15
16void iterator_destroy(iterator_t* iterator) {
17 if(iterator) {
18 free(iterator);
19 }
20}
21
22iterator_t* iterator_create(list_t* list) {
23 iterator_t* iterator = (iterator_t*) malloc(sizeof(iterator_t));
24 if(iterator == NULL) {
25 return NULL;
26 }
27 memset(iterator, '\0', sizeof(iterator_t));
28
29 if(list != NULL) {
30 // Create and bind to list
31
32 } else {
33 // Empty Iterator
34 }
35
36 return iterator;
37}
38
39object_t* iterator_next(iterator_t* iterator) {
40 return NULL;
41}
42
43int iterator_bind(iterator_t* iterator, list_t* list) {
44 return -1;
45}
diff --git a/libcnary/list.c b/libcnary/list.c
new file mode 100644
index 0000000..b98cde8
--- /dev/null
+++ b/libcnary/list.c
@@ -0,0 +1,31 @@
1/*
2 * list.c
3 *
4 * Created on: Mar 8, 2011
5 * Author: posixninja
6 */
7
8#include <stdio.h>
9#include <stdlib.h>
10
11#include "list.h"
12
13void list_init(list_t* list) {
14 list->next = NULL;
15 list->prev = list;
16}
17
18
19void list_destroy(list_t* list) {
20 if(list) {
21 free(list);
22 }
23}
24
25int list_add(list_t* list, object_t* object) {
26 return -1;
27}
28
29int list_remove(list_t* list, object_t* object) {
30 return -1;
31}
diff --git a/libcnary/node.c b/libcnary/node.c
new file mode 100644
index 0000000..956ba2f
--- /dev/null
+++ b/libcnary/node.c
@@ -0,0 +1,207 @@
1/*
2 * node.c
3 *
4 * Created on: Mar 7, 2011
5 * Author: posixninja
6 */
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10
11#include "node.h"
12#include "node_list.h"
13#include "node_iterator.h"
14
15void node_destroy(node_t* node) {
16 if(!node) return;
17
18 if (node->children && node->children->count > 0) {
19 node_t* ch;
20 while ((ch = node->children->begin)) {
21 node_list_remove(node->children, ch);
22 node_destroy(ch);
23 }
24 }
25 node_list_destroy(node->children);
26 node->children = NULL;
27
28 free(node);
29}
30
31node_t* node_create(node_t* parent, void* data) {
32 int error = 0;
33
34 node_t* node = (node_t*) malloc(sizeof(node_t));
35 if(node == NULL) {
36 return NULL;
37 }
38 memset(node, '\0', sizeof(node_t));
39
40 node->data = data;
41 node->depth = 0;
42 node->next = NULL;
43 node->prev = NULL;
44 node->count = 0;
45 node->isLeaf = TRUE;
46 node->isRoot = TRUE;
47 node->parent = NULL;
48 node->children = node_list_create(node);
49
50 // Pass NULL to create a root node
51 if(parent != NULL) {
52 // This is a child node so attach it to it's parent
53 error = node_attach(parent, node);
54 if(error < 0) {
55 // Unable to attach nodes
56 printf("ERROR: %d \"Unable to attach nodes\"\n", error);
57 node_destroy(node);
58 return NULL;
59 }
60 }
61
62 return node;
63}
64
65int node_attach(node_t* parent, node_t* child) {
66 if (!parent || !child) return -1;
67 child->isLeaf = TRUE;
68 child->isRoot = FALSE;
69 child->parent = parent;
70 child->depth = parent->depth + 1;
71 if(parent->isLeaf == TRUE) {
72 parent->isLeaf = FALSE;
73 }
74 int res = node_list_add(parent->children, child);
75 if (res == 0) {
76 parent->count++;
77 }
78 return res;
79}
80
81int node_detach(node_t* parent, node_t* child) {
82 if (!parent || !child) return 0;
83 if (node_list_remove(parent->children, child) == 0) {
84 parent->count--;
85 }
86 return 0;
87}
88
89int node_insert(node_t* parent, unsigned int index, node_t* child)
90{
91 if (!parent || !child) return;
92 child->isLeaf = TRUE;
93 child->isRoot = FALSE;
94 child->parent = parent;
95 child->depth = parent->depth + 1;
96 if(parent->isLeaf == TRUE) {
97 parent->isLeaf = FALSE;
98 }
99 int res = node_list_insert(parent->children, index, child);
100 if (res == 0) {
101 parent->count++;
102 }
103 return res;
104}
105
106void node_debug(node_t* node) {
107 int i = 0;
108 node_t* current = NULL;
109 node_iterator_t* iter = NULL;
110 for(i = 0; i < node->depth; i++) {
111 printf("\t");
112 }
113 if(node->isRoot) {
114 printf("ROOT\n");
115 }
116
117 if(node->isLeaf && !node->isRoot) {
118 printf("LEAF\n");
119
120 } else {
121 if(!node->isRoot) {
122 printf("NODE\n");
123 }
124 iter = node_iterator_create(node->children);
125 for(current = iter->begin; current != NULL; current = iter->next(iter)) {
126 node_debug(current);
127 }
128 }
129
130}
131
132unsigned int node_n_children(struct node_t* node)
133{
134 if (!node) return 0;
135 return node->count;
136}
137
138node_t* node_nth_child(struct node_t* node, unsigned int n)
139{
140 if (!node || !node->children || !node->children->begin) return NULL;
141 int index = 0;
142 int found = 0;
143 node_t *ch;
144 for (ch = node_first_child(node); ch; ch = node_next_sibling(ch)) {
145 if (index++ == n) {
146 found = 1;
147 break;
148 }
149 }
150 if (!found) {
151 return NULL;
152 }
153 return ch;
154}
155
156node_t* node_first_child(struct node_t* node)
157{
158 if (!node || !node->children) return NULL;
159 return node->children->begin;
160}
161
162node_t* node_prev_sibling(struct node_t* node)
163{
164 if (!node) return NULL;
165 return node->prev;
166}
167
168node_t* node_next_sibling(struct node_t* node)
169{
170 if (!node) return NULL;
171 return node->next;
172}
173
174int node_child_position(struct node_t* parent, node_t* child)
175{
176 if (!parent || !parent->children || !parent->children->begin || !child) return -1;
177 int index = 0;
178 int found = 0;
179 node_t *ch;
180 for (ch = node_first_child(parent); ch; ch = node_next_sibling(ch)) {
181 if (ch == child) {
182 found = 1;
183 break;
184 }
185 index++;
186 }
187 if (!found) {
188 return -1;
189 }
190 return index;
191}
192
193node_t* node_copy_deep(node_t* node, copy_func_t copy_func)
194{
195 if (!node) return NULL;
196 void *data;
197 if (copy_func) {
198 data = copy_func(node->data);
199 }
200 node_t* copy = node_create(NULL, data);
201 node_t* ch;
202 for (ch = node_first_child(node); ch; ch = node_next_sibling(ch)) {
203 node_t* cc = node_copy_deep(ch, copy_func);
204 node_attach(copy, cc);
205 }
206 return copy;
207}
diff --git a/libcnary/node_iterator.c b/libcnary/node_iterator.c
new file mode 100644
index 0000000..eef3a4f
--- /dev/null
+++ b/libcnary/node_iterator.c
@@ -0,0 +1,64 @@
1/*
2 * node_iterator.c
3 *
4 * Created on: Mar 8, 2011
5 * Author: posixninja
6 */
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11
12#include "node.h"
13#include "node_list.h"
14#include "node_iterator.h"
15
16void node_iterator_destroy(node_iterator_t* iterator) {
17 if(iterator) {
18 free(iterator);
19 }
20}
21
22node_iterator_t* node_iterator_create(node_list_t* list) {
23 node_iterator_t* iterator = (node_iterator_t*) malloc(sizeof(node_iterator_t));
24 if(iterator == NULL) {
25 return NULL;
26 }
27 memset(iterator, '\0', sizeof(node_iterator_t));
28
29 iterator->count = 0;
30 iterator->position = 0;
31
32 iterator->end = NULL;
33 iterator->begin = NULL;
34 iterator->value = list->begin;
35
36 iterator->list = NULL;
37 iterator->next = node_iterator_next;
38 iterator->bind = node_iterator_bind;
39
40
41 if(list != NULL) {
42 iterator->bind(iterator, list);
43 }
44
45 return iterator;
46}
47
48node_t* node_iterator_next(node_iterator_t* iterator) {
49 node_t* node = iterator->value;
50 if (node) {
51 iterator->value = node->next;
52 }
53 iterator->position++;
54 return node;
55}
56
57int node_iterator_bind(node_iterator_t* iterator, node_list_t* list) {
58 iterator->position = 0;
59 iterator->end = list->end;
60 iterator->count = list->count;
61 iterator->begin = list->begin;
62 iterator->value = list->begin;
63 return 0;
64}
diff --git a/libcnary/node_list.c b/libcnary/node_list.c
new file mode 100644
index 0000000..8464af2
--- /dev/null
+++ b/libcnary/node_list.c
@@ -0,0 +1,130 @@
1/*
2 * node_list.c
3 *
4 * Created on: Mar 8, 2011
5 * Author: posixninja
6 */
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11
12#include "list.h"
13#include "node.h"
14#include "node_list.h"
15
16void node_list_destroy(node_list_t* list) {
17 if(list != NULL) {
18 list_destroy((list_t*) list);
19 }
20}
21
22node_list_t* node_list_create(node_t* node) {
23 node_list_t* list = (node_list_t*) malloc(sizeof(node_list_t));
24 if(list == NULL) {
25 return NULL;
26 }
27 memset(list, '\0', sizeof(node_list_t));
28
29 // Initialize structure
30 list_init((list_t*) list);
31 list->count = 0;
32 return list;
33}
34
35int node_list_add(node_list_t* list, node_t* node) {
36 if (!list || !node) return -1;
37
38 // Find the last element in the list
39 node_t* last = list->end;
40
41 // Setup our new node as the new last element
42 node->next = NULL;
43 node->prev = last;
44
45 // Set the next element of our old "last" element
46 last->next = node;
47
48 // Set the lists prev to the new last element
49 list->end = node;
50
51 // Increment our node count for this list
52 list->count++;
53 return 0;
54}
55
56int node_list_insert(node_list_t* list, unsigned int index, node_t* node) {
57 if (!list || !node) return -1;
58 if (index >= list->count) {
59 return node_list_add(list, node);
60 }
61
62 // Get the first element in the list
63 node_t* cur = list->begin;
64
65 unsigned int pos = 0;
66 node_t* prev = NULL;
67
68 if (index > 0) {
69 while (pos < index) {
70 prev = cur;
71 cur = cur->next;
72 pos++;
73 }
74 }
75
76 if (prev) {
77 // Set previous node
78 node->prev = prev;
79 // Set next node of our new node to next node of the previous node
80 node->next = prev->next;
81 // Set next node of previous node to our new node
82 prev->next = node;
83 } else {
84 node->prev = NULL;
85 // get old first element in list
86 node->next = list->begin;
87 // set new node as first element in list
88 list->begin = node;
89 }
90
91 if (node->next == NULL) {
92 // Set the lists prev to the new last element
93 list->end = node;
94 } else {
95 // set prev of the new next element to our node
96 node->next->prev = node;
97 }
98
99 // Increment our node count for this list
100 list->count++;
101 return 0;
102}
103
104int node_list_remove(node_list_t* list, node_t* node) {
105 if (!list || !node) return -1;
106 if (list->count == 0) return -1;
107
108 node_t* n;
109 for (n = list->begin; n; n = n->next) {
110 if (node == n) {
111 node_t* newnode = node->next;
112 if (node->prev) {
113 node->prev->next = newnode;
114 if (newnode) {
115 newnode->prev = node->prev;
116 }
117 } else {
118 // we just removed the first element
119 if (newnode) {
120 newnode->prev = NULL;
121 }
122 list->begin = newnode;
123 }
124 list->count--;
125 return 0;
126 }
127 }
128 return -1;
129}
130