aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKatharina Fey <kookie@spacekookie.de>2016-08-21 16:57:32 +0200
committerKatharina Fey <kookie@spacekookie.de>2016-08-21 16:57:32 +0200
commit98a9a31789203e051404b9bcf2faa29bafd9e4bf (patch)
treef66c4b872bf90e0265a12236136f1ede63bb3911
parent9d3395a98ff79596444796ba694be0ed1c8a8248 (diff)
Adding recursive search function
-rw-r--r--include/dtree/dyn_tree.h18
-rw-r--r--lib/dyn_tree.c45
2 files changed, 61 insertions, 2 deletions
diff --git a/include/dtree/dyn_tree.h b/include/dtree/dyn_tree.h
index d08d261..64b463b 100644
--- a/include/dtree/dyn_tree.h
+++ b/include/dtree/dyn_tree.h
@@ -37,7 +37,7 @@ extern "C" {
/* Type that determines what data is stored inside a tree-node */
-typedef enum {
+typedef enum dt_uni_t {
UNSET, LITERAL, NUMERAL, RECURSIVE, PAIR, POINTER
} dt_uni_t;
@@ -48,7 +48,7 @@ typedef struct dtree {
size_t size, used;
union {
char *literal;
- int numeral;
+ long numeral;
struct dtree *(*recursive);
void *pointer;
} payload;
@@ -182,6 +182,20 @@ dt_err dtree_split_trees(dtree *data, dtree *sp);
*/
dt_err dtree_merge_trees(dtree *data, dtree *merge);
+
+/**
+ * Recursive tree search function that will return the first occurence match
+ * to a provided payload (with an exact type). If you have data duplication
+ * in your tree this _might_ return some false positives.
+ *
+ * @param data Root reference to search
+ * @param found Empty pointer to put found node into
+ * @param payload What should be found
+ * @param type What type of data should be found
+ * @return
+ */
+dt_err dtree_search_payload(dtree *data, dtree *(*found), void *payload, dt_uni_t type);
+
/**
* A retrieve function to get data back from a node that doesn't require
* you to manually access parts of the struct.
diff --git a/lib/dyn_tree.c b/lib/dyn_tree.c
index 2cf100d..5035849 100644
--- a/lib/dyn_tree.c
+++ b/lib/dyn_tree.c
@@ -261,6 +261,51 @@ dt_err dtree_merge_trees(dtree *data, dtree *merge)
}
+dt_err dtree_search_payload(dtree *data, dtree *(*found), void *payload, dt_uni_t type)
+{
+ if(data == NULL) return INVALID_PARAMS;
+
+ /* Make sure our pointer is clean */
+ *found = NULL;
+
+ if(data->type == RECURSIVE|| data->type == PAIR) {
+
+ int i;
+ for(i = 0; i < data->used; i++) {
+ dt_err err = dtree_search_payload(data->payload.recursive[i], found, payload, type);
+ if(err == SUCCESS) return SUCCESS;
+ }
+
+ } else {
+
+ /* Check the type aligns */
+ if(data->type != type) return NODE_NOT_FOUND;
+
+ switch(type) {
+ case LITERAL:
+ if(strcmp(data->payload.literal, (char*) payload) == 0)
+ *found = data;
+ break;
+
+ case NUMERAL:
+ if(data->payload.numeral == (long) payload)
+ *found = data;
+ break;
+
+ case POINTER:
+ if(data->payload.pointer == payload)
+ *found = data;
+ break;
+
+ default: return NODE_NOT_FOUND;
+ }
+
+ }
+
+ return (*found == NULL) ? NODE_NOT_FOUND : SUCCESS;
+}
+
+
void recursive_print(dtree *data, const char *offset)
{
dt_uni_t type = data->type;