roza/lib/node.c

100 lines
2.1 KiB
C

#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->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;
}
void node_add_new_child(node_t* node, node_t* child)
{
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->children.size++;
}
node_t* node_child(node_t* node, size_t index)
{
assert(node);
assert(index < node->children.size);
return (node_t*) node->children.data[index];
}
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;
}