fprintf(out, "%s\n", type->name);
}
-struct ec_node *__ec_node(const struct ec_node_type *type, const char *id)
+struct ec_node *ec_node_from_type(const struct ec_node_type *type, const char *id)
{
struct ec_node *node = NULL;
return NULL;
}
+const struct ec_config_schema *
+ec_node_type_schema(const struct ec_node_type *type)
+{
+ return type->schema;
+}
+
+const char *
+ec_node_type_name(const struct ec_node_type *type)
+{
+ return type->name;
+}
+
struct ec_node *ec_node(const char *typename, const char *id)
{
const struct ec_node_type *type;
return NULL;
}
- return __ec_node(type, id);
+ return ec_node_from_type(type, id);
}
static void count_references(struct ec_node *node, unsigned int refs)
{
struct ec_node *child;
size_t i, n;
+ int ret;
if (node->free.state == EC_NODE_FREE_STATE_TRAVERSED) {
node->free.refcnt += refs;
node->free.state = EC_NODE_FREE_STATE_TRAVERSED;
n = ec_node_get_children_count(node);
for (i = 0; i < n; i++) {
- child = ec_node_get_child(node, i);
- refs = ec_node_get_child_refs(node, i);
+ ret = ec_node_get_child(node, i, &child, &refs);
+ assert(ret == 0);
count_references(child, refs);
}
}
static void mark_freeable(struct ec_node *node, enum ec_node_free_state mark)
{
struct ec_node *child;
+ unsigned int refs;
size_t i, n;
+ int ret;
if (mark == node->free.state)
return;
n = ec_node_get_children_count(node);
for (i = 0; i < n; i++) {
- child = ec_node_get_child(node, i);
+ ret = ec_node_get_child(node, i, &child, &refs);
+ assert(ret == 0);
mark_freeable(child, mark);
}
}
static void reset_mark(struct ec_node *node)
{
struct ec_node *child;
+ unsigned int refs;
size_t i, n;
+ int ret;
if (node->free.state == EC_NODE_FREE_STATE_NONE)
return;
n = ec_node_get_children_count(node);
for (i = 0; i < n; i++) {
- child = ec_node_get_child(node, i);
+ ret = ec_node_get_child(node, i, &child, &refs);
+ assert(ret == 0);
reset_mark(child);
}
}
return node->type->get_children_count(node);
}
-struct ec_node *
-ec_node_get_child(const struct ec_node *node, size_t i)
+int
+ec_node_get_child(const struct ec_node *node, size_t i,
+ struct ec_node **child, unsigned int *refs)
{
+ *child = NULL;
+ *refs = 0;
if (node->type->get_child == NULL)
- return NULL;
- return node->type->get_child(node, i);
-}
-
-unsigned int
-ec_node_get_child_refs(const struct ec_node *node, size_t i)
-{
- if (node->type->get_child_refs == NULL)
- return 1;
- return node->type->get_child_refs(node, i);
+ return -1;
+ return node->type->get_child(node, i, child, refs);
}
int
errno = EINVAL;
goto fail;
}
- if (ec_config_validate(config, node->type->schema,
- node->type->schema_len) < 0)
+ if (ec_config_validate(config, node->type->schema) < 0)
goto fail;
if (node->type->set_config != NULL) {
if (node->type->set_config(node, config) < 0)
struct ec_node *ec_node_find(struct ec_node *node, const char *id)
{
- struct ec_node *child, *ret;
+ struct ec_node *child, *retnode;
const char *node_id = ec_node_id(node);
+ unsigned int refs;
size_t i, n;
+ int ret;
if (id != NULL && node_id != NULL && !strcmp(node_id, id))
return node;
n = ec_node_get_children_count(node);
for (i = 0; i < n; i++) {
- child = ec_node_get_child(node, i);
- ret = ec_node_find(child, id);
- if (ret != NULL)
- return ret;
+ ret = ec_node_get_child(node, i, &child, &refs);
+ assert(ret == 0);
+ retnode = ec_node_find(child, id);
+ if (retnode != NULL)
+ return retnode;
}
return NULL;
{
const char *id, *typename;
struct ec_node *child;
+ unsigned int refs;
char buf[32];
size_t i, n;
+ int ret;
id = ec_node_id(node);
typename = node->type->name;
n = ec_node_get_children_count(node);
for (i = 0; i < n; i++) {
- child = ec_node_get_child(node, i);
+ ret = ec_node_get_child(node, i, &child, &refs);
+ assert(ret == 0);
__ec_node_dump(out, child, indent + 1, dict);
}
}
+/* XXX this is too much debug-oriented, we should have a parameter or 2 funcs */
void ec_node_dump(FILE *out, const struct ec_node *node)
{
struct ec_keyval *dict = NULL;
{
struct ec_node *node = NULL, *expr = NULL;
struct ec_node *expr2 = NULL, *val = NULL, *op = NULL, *seq = NULL;
- const struct ec_node *child;
const struct ec_node_type *type;
+ struct ec_node *child;
+ unsigned int refs;
FILE *f = NULL;
char *buf = NULL;
size_t buflen = 0;
testres |= EC_TEST_CHECK(
ec_node_get_children_count(node) == 2,
"bad children count\n");
- child = ec_node_get_child(node, 0);
- testres |= EC_TEST_CHECK(child != NULL &&
+ ret = ec_node_get_child(node, 0, &child, &refs);
+ testres |= EC_TEST_CHECK(ret == 0 &&
+ child != NULL &&
!strcmp(ec_node_type(child)->name, "str") &&
!strcmp(ec_node_id(child), "id_x"),
"bad child 0");
- child = ec_node_get_child(node, 1);
- testres |= EC_TEST_CHECK(child != NULL &&
+ ret = ec_node_get_child(node, 1, &child, &refs);
+ testres |= EC_TEST_CHECK(ret == 0 &&
+ child != NULL &&
!strcmp(ec_node_type(child)->name, "str") &&
!strcmp(ec_node_id(child), "id_y"),
"bad child 1");
- child = ec_node_get_child(node, 2);
+ ret = ec_node_get_child(node, 2, &child, &refs);
+ testres |= EC_TEST_CHECK(ret != 0,
+ "ret should be != 0");
testres |= EC_TEST_CHECK(child == NULL,
"child 2 should be NULL");