roza/lib/node.c

139 lines
2.7 KiB
C
Raw Permalink Normal View History

2023-12-09 17:24:41 +00:00
#include "node.h"
RZ_ENUM_C(NodeType, NODE_TYPE);
void node_init(node_t* node, NodeType type, char* value, int line)
{
assert(node);
assert(value);
node->type = type;
str_init(&node->value);
str_append(&node->value, value);
node->line = line;
node->parent = NULL;
2023-12-09 17:24:41 +00:00
node->children.size = 0;
node->children.cap = 0;
node->children.data = NULL;
}
void node_free(node_t* node)
{
assert(node);
str_free(&node->value);
for (size_t i=0; i<node->children.size; i++)
{
node_free((node_t*) node->children.data[i]);
free(node->children.data[i]);
}
free(node->children.data);
node->children.size = 0;
node->children.cap = 0;
}
node_t* node_try_find_parent(node_t* node, NodeType type)
{
assert(node);
node_t* itr = node;
while (itr && itr->type != type)
{
itr = (node_t*) itr->parent;
}
return itr;
}
2023-12-11 17:01:22 +00:00
void node_add_new_child(node_t* node, node_t* child)
2023-12-09 17:24:41 +00:00
{
assert(node);
assert(child);
if (node->children.cap == 0)
{
node->children.cap = 2;
node->children.data = malloc(sizeof(node_t) * node->children.cap);
}
if (node->children.size >= node->children.cap)
{
node->children.cap *= 2;
node->children.data = realloc(node->children.data,
sizeof(node_t) * node->children.cap);
}
size_t sz = node->children.size;
node->children.data[sz] = (struct node_t*) child;
((node_t*) node->children.data[sz])->parent = (struct node_t*) node;
2023-12-09 17:24:41 +00:00
node->children.size++;
}
2023-12-11 17:01:22 +00:00
node_t* node_child(node_t* node, size_t index)
{
assert(node);
assert(index < node->children.size);
return (node_t*) node->children.data[index];
}
2023-12-09 17:24:41 +00:00
size_t node_str(node_t* node, char* buffer, size_t size)
{
assert(node);
size_t sz = 0;
sz += snprintf(buffer + sz, size - sz, "%s",
NodeTypeStr[node->type] + strlen("NODE_"));
if (!str_empty(&node->value))
{
sz += snprintf(buffer + sz, size - sz, "[%s]", node->value.data);
}
if (node->children.size > 0)
{
sz += snprintf(buffer +sz, size - sz, "(");
for (size_t i=0; i<node->children.size; i++)
{
if (i > 0)
{
sz += snprintf(buffer +sz, size - sz, ",");
}
sz += node_str((node_t*) node->children.data[i], buffer + sz, size - sz);
}
sz += snprintf(buffer +sz, size - sz, ")");
}
return sz;
}
2023-12-16 18:42:26 +00:00
node_t* node_find_first(node_t* node, NodeType type)
{
assert(node);
if (node->type == type)
{
return node;
}
for (size_t i=0; i<node->children.size; i++)
{
node_t* child = node_find_first((node_t*) node->children.data[i], type);
if (child)
{
return child;
}
}
return NULL;
}