if (node->type != NULL && node->type->free_priv != NULL)
node->type->free_priv(node);
- ec_free(node->children);
ec_free(node->id);
ec_free(node->desc);
ec_keyval_free(node->attrs);
size_t ec_node_get_children_count(const struct ec_node *node)
{
- return node->n_children;
+ if (node->type->get_children_count == NULL)
+ return 0;
+ return node->type->get_children_count(node);
}
struct ec_node *
ec_node_get_child(const struct ec_node *node, size_t i)
{
- if (i >= ec_node_get_children_count(node))
+ if (node->type->get_child == NULL)
return NULL;
- return node->children[i];
-}
-
-int ec_node_add_child(struct ec_node *node, struct ec_node *child)
-{
- struct ec_node **children = NULL;
- size_t n;
-
- if (node == NULL || child == NULL) {
- errno = EINVAL;
- goto fail;
- }
-
- n = node->n_children;
- children = ec_realloc(node->children,
- (n + 1) * sizeof(child));
- if (children == NULL)
- goto fail;
-
- children[n] = child;
- node->children = children;
- node->n_children = n + 1;
-
- return 0;
-
-fail:
- ec_free(children);
- assert(errno != 0);
- return -1;
+ return node->type->get_child(node, i);
}
int
return node->config;
}
-#if 0 /* later */
-int ec_node_del_child(struct ec_node *node, struct ec_node *child)
-{
- size_t i, n;
-
- if (node == NULL || child == NULL)
- goto fail;
-
- n = node->n_children;
- for (i = 0; i < n; i++) {
- if (node->children[i] != child)
- continue;
- memcpy(&node->children[i], &node->children[i+1],
- (n - i - 1) * sizeof(child));
- return 0;
- }
-
-fail:
- errno = EINVAL;
- return -1;
-}
-#endif
-
struct ec_node *ec_node_find(struct ec_node *node, const char *id)
{
struct ec_node *child, *ret;
if (id != NULL && node_id != NULL && !strcmp(node_id, id))
return node;
- n = node->n_children;
+ n = ec_node_get_children_count(node);
for (i = 0; i < n; i++) {
- child = node->children[i];
+ child = ec_node_get_child(node, i);
ret = ec_node_find(child, id);
if (ret != NULL)
return ret;
fprintf(out, "%*s" "type=%s id=%s %p\n",
(int)indent * 4, "", typename, id, node);
- n = node->n_children;
+ n = ec_node_get_children_count(node);
for (i = 0; i < n; i++) {
- child = node->children[i];
+ child = ec_node_get_child(node, i);
__ec_node_dump(out, child, indent + 1);
}
}
typedef const char * (*ec_node_desc_t)(const struct ec_node *);
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);
/**
* A structure describing a node type.
size_t size;
ec_node_init_priv_t init_priv;
ec_node_free_priv_t free_priv;
+ ec_node_get_children_count_t get_children_count;
+ ec_node_get_child_t get_child;
};
/**
char *desc;
struct ec_keyval *attrs;
unsigned int refcnt;
- struct ec_node **children; /* array of children */
- size_t n_children; /* number of children in the array */
};
/* create a new node when the type is known, typically called from the node
if (cmd == NULL)
goto fail;
- gen_node->n_children = 0; /* XXX */
- TAILQ_FOREACH(child, &children->list, next) {
- /* XXX if it fails... too late */
- if (ec_node_add_child(gen_node, child->node) < 0)
- goto fail;
- }
-
ec_node_free(node->cmd);
node->cmd = cmd;
ec_free(node->cmd_str);
return -1;
}
+static size_t
+ec_node_cmd_get_children_count(const struct ec_node *gen_node)
+{
+ struct ec_node_cmd *node = (struct ec_node_cmd *)gen_node;
+ return node->len;
+}
+
+static struct ec_node *
+ec_node_cmd_get_child(const struct ec_node *gen_node, size_t i)
+{
+ struct ec_node_cmd *node = (struct ec_node_cmd *)gen_node;
+
+ if (i >= node->len)
+ return NULL;
+
+ return node->table[i];
+}
+
static struct ec_node_type ec_node_cmd_type = {
.name = "cmd",
.schema = ec_node_cmd_schema,
.complete = ec_node_cmd_complete,
.size = sizeof(struct ec_node_cmd),
.free_priv = ec_node_cmd_free_priv,
+ .get_children_count = ec_node_cmd_get_children_count,
+ .get_child = ec_node_cmd_get_child,
};
EC_NODE_TYPE_REGISTER(ec_node_cmd_type);
ec_node_free(node->child);
}
+static size_t
+ec_node_many_get_children_count(const struct ec_node *gen_node)
+{
+ struct ec_node_many *node = (struct ec_node_many *)gen_node;
+
+ if (node->child)
+ return 1;
+ return 0;
+}
+
+static struct ec_node *
+ec_node_many_get_child(const struct ec_node *gen_node, size_t i)
+{
+ struct ec_node_many *node = (struct ec_node_many *)gen_node;
+
+ if (i >= 1)
+ return NULL;
+
+ return node->child;
+}
+
static struct ec_node_type ec_node_many_type = {
.name = "many",
.parse = ec_node_many_parse,
.complete = ec_node_many_complete,
.size = sizeof(struct ec_node_many),
.free_priv = ec_node_many_free_priv,
+ .get_children_count = ec_node_many_get_children_count,
+ .get_child = ec_node_many_get_child,
};
EC_NODE_TYPE_REGISTER(ec_node_many_type);
if (child == NULL)
return NULL;
- // XXX ec_node_add_child()
node = (struct ec_node_many *)__ec_node(&ec_node_many_type, id);
if (node == NULL) {
ec_node_free(child);
ec_node_free(node->child);
}
+static size_t
+ec_node_once_get_children_count(const struct ec_node *gen_node)
+{
+ struct ec_node_once *node = (struct ec_node_once *)gen_node;
+
+ if (node->child)
+ return 1;
+ return 0;
+}
+
+static struct ec_node *
+ec_node_once_get_child(const struct ec_node *gen_node, size_t i)
+{
+ struct ec_node_once *node = (struct ec_node_once *)gen_node;
+
+ if (i >= 1)
+ return NULL;
+
+ return node->child;
+}
+
static struct ec_node_type ec_node_once_type = {
.name = "once",
.parse = ec_node_once_parse,
.complete = ec_node_once_complete,
.size = sizeof(struct ec_node_once),
.free_priv = ec_node_once_free_priv,
+ .get_children_count = ec_node_once_get_children_count,
+ .get_child = ec_node_once_get_child,
};
EC_NODE_TYPE_REGISTER(ec_node_once_type);
if (ec_node_check_type(gen_node, &ec_node_once_type) < 0)
goto fail;
- if (ec_node_add_child(gen_node, child) < 0)
- goto fail;
-
node->child = child;
return 0;
ec_node_free(node->child);
}
+static size_t
+ec_node_option_get_children_count(const struct ec_node *gen_node)
+{
+ struct ec_node_option *node = (struct ec_node_option *)gen_node;
+
+ if (node->child)
+ return 1;
+ return 0;
+}
+
+static struct ec_node *
+ec_node_option_get_child(const struct ec_node *gen_node, size_t i)
+{
+ struct ec_node_option *node = (struct ec_node_option *)gen_node;
+
+ if (i >= 1)
+ return NULL;
+
+ return node->child;
+}
+
static struct ec_node_type ec_node_option_type = {
.name = "option",
.parse = ec_node_option_parse,
.complete = ec_node_option_complete,
.size = sizeof(struct ec_node_option),
.free_priv = ec_node_option_free_priv,
+ .get_children_count = ec_node_option_get_children_count,
+ .get_child = ec_node_option_get_child,
};
EC_NODE_TYPE_REGISTER(ec_node_option_type);
if (ec_node_check_type(gen_node, &ec_node_option_type) < 0)
goto fail;
- if (ec_node_add_child(gen_node, child) < 0)
- goto fail;
-
node->child = child;
return 0;
ec_free(node->table);
}
+static size_t
+ec_node_or_get_children_count(const struct ec_node *gen_node)
+{
+ struct ec_node_or *node = (struct ec_node_or *)gen_node;
+ return node->len;
+}
+
+static struct ec_node *
+ec_node_or_get_child(const struct ec_node *gen_node, size_t i)
+{
+ struct ec_node_or *node = (struct ec_node_or *)gen_node;
+
+ if (i >= node->len)
+ return NULL;
+
+ return node->table[i];
+}
+
static struct ec_node_type ec_node_or_type = {
.name = "or",
.parse = ec_node_or_parse,
.complete = ec_node_or_complete,
.size = sizeof(struct ec_node_or),
.free_priv = ec_node_or_free_priv,
+ .get_children_count = ec_node_or_get_children_count,
+ .get_child = ec_node_or_get_child,
};
EC_NODE_TYPE_REGISTER(ec_node_or_type);
goto fail;
node->table = table;
-
- if (ec_node_add_child(gen_node, child) < 0)
- goto fail;
-
table[node->len] = child;
node->len++;
ec_free(node->table);
}
+static size_t
+ec_node_seq_get_children_count(const struct ec_node *gen_node)
+{
+ struct ec_node_seq *node = (struct ec_node_seq *)gen_node;
+ return node->len;
+}
+
+static struct ec_node *
+ec_node_seq_get_child(const struct ec_node *gen_node, size_t i)
+{
+ struct ec_node_seq *node = (struct ec_node_seq *)gen_node;
+
+ if (i >= node->len)
+ return NULL;
+
+ return node->table[i];
+}
+
static struct ec_node_type ec_node_seq_type = {
.name = "seq",
.parse = ec_node_seq_parse,
.complete = ec_node_seq_complete,
.size = sizeof(struct ec_node_seq),
.free_priv = ec_node_seq_free_priv,
+ .get_children_count = ec_node_seq_get_children_count,
+ .get_child = ec_node_seq_get_child,
};
EC_NODE_TYPE_REGISTER(ec_node_seq_type);
goto fail;
node->table = table;
-
- if (ec_node_add_child(gen_node, child) < 0)
- goto fail;
-
table[node->len] = child;
node->len++;
ec_free(node->table);
}
+static size_t
+ec_node_subset_get_children_count(const struct ec_node *gen_node)
+{
+ struct ec_node_subset *node = (struct ec_node_subset *)gen_node;
+ return node->len;
+}
+
+static struct ec_node *
+ec_node_subset_get_child(const struct ec_node *gen_node, size_t i)
+{
+ struct ec_node_subset *node = (struct ec_node_subset *)gen_node;
+
+ if (i >= node->len)
+ return NULL;
+
+ return node->table[i];
+}
+
static struct ec_node_type ec_node_subset_type = {
.name = "subset",
.parse = ec_node_subset_parse,
.complete = ec_node_subset_complete,
.size = sizeof(struct ec_node_subset),
.free_priv = ec_node_subset_free_priv,
+ .get_children_count = ec_node_subset_get_children_count,
+ .get_child = ec_node_subset_get_child,
};
EC_NODE_TYPE_REGISTER(ec_node_subset_type);
}
node->table = table;
-
- if (ec_node_add_child(gen_node, child) < 0)
- goto fail;
-
table[node->len] = child;
node->len++;
condition <watchpoint num> malloc_seq == <value + 1>
run <args...>
c
+
+
+---------------
+
+