{
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
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);
}
}
{
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");
typedef int (*ec_node_init_priv_t)(struct ec_node *);
typedef void (*ec_node_free_priv_t)(struct ec_node *);
typedef size_t (*ec_node_get_children_count_t)(const struct ec_node *);
-typedef struct ec_node * (*ec_node_get_child_t)(const struct ec_node *,
- size_t i);
-typedef unsigned int (*ec_node_get_child_refs_t)(const struct ec_node *,
- size_t i);
+typedef int (*ec_node_get_child_t)(const struct ec_node *,
+ size_t i, struct ec_node **child, unsigned int *refs);
/**
* A structure describing a node type.
ec_node_free_priv_t free_priv;
ec_node_get_children_count_t get_children_count;
ec_node_get_child_t get_child;
- ec_node_get_child_refs_t get_child_refs;
};
/**
const struct ec_config *ec_node_get_config(struct ec_node *node);
size_t ec_node_get_children_count(const struct ec_node *node);
-struct ec_node *
-ec_node_get_child(const struct ec_node *node, size_t i);
-unsigned int
-ec_node_get_child_refs(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);
/* XXX add more accessors */
const struct ec_node_type *ec_node_type(const struct ec_node *node);