diff options
| author | 2011-06-13 18:30:37 +0200 | |
|---|---|---|
| committer | 2011-06-13 18:30:37 +0200 | |
| commit | c7412d4813ccb994fdd219f421eaba8bb37831dd (patch) | |
| tree | 5b7f3016ceb337b31afdd62c9fee646f33e8b271 | |
| parent | 3277a11f0beedda8b5d65ffccb05fabd4e8ded28 (diff) | |
| download | libplist-c7412d4813ccb994fdd219f421eaba8bb37831dd.tar.gz libplist-c7412d4813ccb994fdd219f421eaba8bb37831dd.tar.bz2 | |
Bundle libcnary for better packaging1.5
| -rw-r--r-- | libcnary/CMakeLists.txt | 16 | ||||
| -rw-r--r-- | libcnary/Makefile | 21 | ||||
| -rw-r--r-- | libcnary/README | 5 | ||||
| -rw-r--r-- | libcnary/cnary.c | 30 | ||||
| -rw-r--r-- | libcnary/include/iterator.h | 33 | ||||
| -rw-r--r-- | libcnary/include/list.h | 24 | ||||
| -rw-r--r-- | libcnary/include/node.h | 59 | ||||
| -rw-r--r-- | libcnary/include/node_iterator.h | 39 | ||||
| -rw-r--r-- | libcnary/include/node_list.h | 31 | ||||
| -rw-r--r-- | libcnary/include/object.h | 25 | ||||
| -rw-r--r-- | libcnary/iterator.c | 45 | ||||
| -rw-r--r-- | libcnary/list.c | 31 | ||||
| -rw-r--r-- | libcnary/node.c | 207 | ||||
| -rw-r--r-- | libcnary/node_iterator.c | 64 | ||||
| -rw-r--r-- | libcnary/node_list.c | 130 |
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 @@ | |||
| 1 | cmake_minimum_required(VERSION 2.6) | ||
| 2 | |||
| 3 | SET(libcnary_SRC | ||
| 4 | iterator.c | ||
| 5 | list.c | ||
| 6 | node.c | ||
| 7 | node_iterator.c | ||
| 8 | node_list.c ) | ||
| 9 | |||
| 10 | INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include) | ||
| 11 | |||
| 12 | SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") | ||
| 13 | ADD_LIBRARY(libcnary STATIC ${libcnary_SRC}) | ||
| 14 | |||
| 15 | SET_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 @@ | |||
| 1 | TARGET = cnary | ||
| 2 | LIBRARY = libcnary.a | ||
| 3 | OBJECTS = cnary.o libcnary.a | ||
| 4 | LIBRARY_OBJECTS = node.o list.o iterator.o node_list.o node_iterator.o | ||
| 5 | CFLAGS=-g -I./include -I/opt/local/include -mmacosx-version-min=10.5 -arch i386 -isysroot /Developer/SDKs/MacOSX10.5.sdk | ||
| 6 | LDFLAGS=-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 | |||
| 18 | all: $(TARGET) | ||
| 19 | |||
| 20 | clean: | ||
| 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 @@ | |||
| 1 | Project Name: | ||
| 2 | libcnary | ||
| 3 | |||
| 4 | Project 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 | |||
| 12 | int 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 | |||
| 11 | struct list_t; | ||
| 12 | struct object_t; | ||
| 13 | |||
| 14 | typedef 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 | |||
| 27 | void iterator_destroy(struct iterator_t* iterator); | ||
| 28 | struct iterator_t* iterator_create(struct list_t* list); | ||
| 29 | |||
| 30 | struct object_t* iterator_next(struct iterator_t* iterator); | ||
| 31 | int 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 | |||
| 13 | typedef struct list_t { | ||
| 14 | void* next; | ||
| 15 | void* prev; | ||
| 16 | } list_t; | ||
| 17 | |||
| 18 | void list_init(struct list_t* list); | ||
| 19 | void list_destroy(struct list_t* list); | ||
| 20 | |||
| 21 | int list_add(struct list_t* list, struct object_t* object); | ||
| 22 | int 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 | |||
| 15 | struct node_list_t; | ||
| 16 | |||
| 17 | // This class implements the abstract iterator class | ||
| 18 | typedef 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 | |||
| 40 | void node_destroy(struct node_t* node); | ||
| 41 | struct node_t* node_create(struct node_t* parent, void* data); | ||
| 42 | |||
| 43 | int node_attach(struct node_t* parent, struct node_t* child); | ||
| 44 | int node_detach(struct node_t* parent, struct node_t* child); | ||
| 45 | int node_insert(struct node_t* parent, unsigned int index, struct node_t* child); | ||
| 46 | |||
| 47 | unsigned int node_n_children(struct node_t* node); | ||
| 48 | node_t* node_nth_child(struct node_t* node, unsigned int n); | ||
| 49 | node_t* node_first_child(struct node_t* node); | ||
| 50 | node_t* node_prev_sibling(struct node_t* node); | ||
| 51 | node_t* node_next_sibling(struct node_t* node); | ||
| 52 | int node_child_position(struct node_t* parent, node_t* child); | ||
| 53 | |||
| 54 | typedef void* (*copy_func_t)(const void *src); | ||
| 55 | node_t* node_copy_deep(node_t* node, copy_func_t copy_func); | ||
| 56 | |||
| 57 | void 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 | ||
| 15 | typedef 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 | |||
| 33 | void node_iterator_destroy(node_iterator_t* iterator); | ||
| 34 | node_iterator_t* node_iterator_create(node_list_t* list); | ||
| 35 | |||
| 36 | struct node_t* node_iterator_next(struct node_iterator_t* iterator); | ||
| 37 | int 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 | |||
| 11 | struct node_t; | ||
| 12 | |||
| 13 | // This class implements the list_t abstract class | ||
| 14 | typedef 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 | |||
| 24 | void node_list_destroy(struct node_list_t* list); | ||
| 25 | struct node_list_t* node_list_create(struct node_t* node); | ||
| 26 | |||
| 27 | int node_list_add(node_list_t* list, node_t* node); | ||
| 28 | int node_list_insert(node_list_t* list, unsigned int index, node_t* node); | ||
| 29 | int 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 | |||
| 19 | typedef 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 | |||
| 16 | void iterator_destroy(iterator_t* iterator) { | ||
| 17 | if(iterator) { | ||
| 18 | free(iterator); | ||
| 19 | } | ||
| 20 | } | ||
| 21 | |||
| 22 | iterator_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 | |||
| 39 | object_t* iterator_next(iterator_t* iterator) { | ||
| 40 | return NULL; | ||
| 41 | } | ||
| 42 | |||
| 43 | int 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 | |||
| 13 | void list_init(list_t* list) { | ||
| 14 | list->next = NULL; | ||
| 15 | list->prev = list; | ||
| 16 | } | ||
| 17 | |||
| 18 | |||
| 19 | void list_destroy(list_t* list) { | ||
| 20 | if(list) { | ||
| 21 | free(list); | ||
| 22 | } | ||
| 23 | } | ||
| 24 | |||
| 25 | int list_add(list_t* list, object_t* object) { | ||
| 26 | return -1; | ||
| 27 | } | ||
| 28 | |||
| 29 | int 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 | |||
| 15 | void 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 | |||
| 31 | node_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 | |||
| 65 | int 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 | |||
| 81 | int 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 | |||
| 89 | int 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 | |||
| 106 | void 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 | |||
| 132 | unsigned int node_n_children(struct node_t* node) | ||
| 133 | { | ||
| 134 | if (!node) return 0; | ||
| 135 | return node->count; | ||
| 136 | } | ||
| 137 | |||
| 138 | node_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 | |||
| 156 | node_t* node_first_child(struct node_t* node) | ||
| 157 | { | ||
| 158 | if (!node || !node->children) return NULL; | ||
| 159 | return node->children->begin; | ||
| 160 | } | ||
| 161 | |||
| 162 | node_t* node_prev_sibling(struct node_t* node) | ||
| 163 | { | ||
| 164 | if (!node) return NULL; | ||
| 165 | return node->prev; | ||
| 166 | } | ||
| 167 | |||
| 168 | node_t* node_next_sibling(struct node_t* node) | ||
| 169 | { | ||
| 170 | if (!node) return NULL; | ||
| 171 | return node->next; | ||
| 172 | } | ||
| 173 | |||
| 174 | int 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 | |||
| 193 | node_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 | |||
| 16 | void node_iterator_destroy(node_iterator_t* iterator) { | ||
| 17 | if(iterator) { | ||
| 18 | free(iterator); | ||
| 19 | } | ||
| 20 | } | ||
| 21 | |||
| 22 | node_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 | |||
| 48 | node_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 | |||
| 57 | int 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 | |||
| 16 | void node_list_destroy(node_list_t* list) { | ||
| 17 | if(list != NULL) { | ||
| 18 | list_destroy((list_t*) list); | ||
| 19 | } | ||
| 20 | } | ||
| 21 | |||
| 22 | node_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 | |||
| 35 | int 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 | |||
| 56 | int 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 | |||
| 104 | int 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 | |||
