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;
|
2023-12-18 13:19:38 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2023-12-18 13:19:38 +00:00
|
|
|
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;
|
2023-12-18 13:19:38 +00:00
|
|
|
((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;
|
|
|
|
}
|