nodesystem/src/node.c

131 lines
3.1 KiB
C

#include "node.h"
#include <stdlib.h>
#include <stdio.h>
NOD_Node* NOD_CreateNode(char* name){
NOD_Node* node = malloc(sizeof(NOD_Node));
if(node != NULL){
node->name = name;
node->parent = NULL;
node->childv = NULL;
node->childc = 0;
}
return node;
}
void NOD_DestroyNode(NOD_Node* node){
if(node != NULL){
free(node);
}
}
void NOD_NodeAddChild(NOD_Node* parent, NOD_Node* child){
if(parent != NULL && child != NULL){
/** Prevent recursion */
if(parent == child){
fprintf(stderr, "NOD_Warning: A node cannot be added to itself.\n");
return;
}
NOD_Node* tmp_parent = parent->parent;
while(tmp_parent != NULL){
if(tmp_parent == child){
fprintf(stderr, "NOD_Warning: Can't add a parent of a node as its child.\n");
return;
}
tmp_parent = tmp_parent->parent;
}
/** Check if child already in vector */
for(int i = 0; i < parent->childc; i++){
if(parent->childv[i] == child){
fprintf(stderr, "NOD_Warning: Tried to add a child already in the vector.\n");
return;
}
}
/** Create child vector if it hasn't been used */
if(parent->childc == 0 || parent->childv == NULL){
parent->childv = malloc(sizeof(child));
if(parent->childv != NULL){
parent->childv[0] = child;
parent->childc = 1;
child->parent = parent;
}
else{
fprintf(stderr,
"NOD_Error: Failed to allocate space for child vector \"%s\"\n",
parent->name);
}
}
/** Realloc if it already exists */
/** I don't test if chilv is null because it
has already been tested */
else if(parent->childc > 0){
parent->childv = realloc(parent->childv,
sizeof(child) * (parent->childc+1));
if(parent->childv != NULL){
parent->childv[parent->childc] = child;
parent->childc++;
child->parent = parent;
}
else{
fprintf(stderr,
"NOD_Error: Failed to reallocate space for child vector \"%s\"\n",
parent->name);
}
}
}
}
void NOD_NodeUnparent(NOD_Node* node){
if(node != NULL && node->parent != NULL){
NOD_Node* parent = node->parent;
for(int i = 0; i < parent->childc; i ++){
if(parent->childv[i] == node){
parent->childv[i] = NULL;
/* Free allocated memory if last child */
if(i + 1 == parent->childc){
fprintf(stderr,
"NOD_Debug: Freeing last child of vector...\n");
parent->childv = realloc(parent->childv, sizeof(node) * parent->childc);
parent->childc--;
}
}
}
node->parent = NULL;
}
}
void NOD_PrintNodeTree(NOD_Node* node){
if(node != NULL){
printf("\"%s\"\n", node->name);
for(int i = 0; i < node->childc; i++){
if(i+1 != node->childc) printf("├── ");
else printf("└── ");
printf("\"%s\"\n", node->childv[i]->name);
}
}
}
int NOD_NodeChildCount(NOD_Node* node){
unsigned int count = 0;
for(int i = 0; i < node->childc; i++){
if(node->childv[i] != NULL) count++;
}
return count;
}