}
int
-ec_node_complete_child(struct ec_node *node, struct ec_completed *completed,
- const struct ec_strvec *strvec)
+ec_node_complete_child(/* XXX const */struct ec_node *node,
+ struct ec_completed *completed,
+ const struct ec_strvec *strvec)
{
struct ec_parsed *child_state, *cur_state;
struct ec_completed_group *cur_group;
int ret;
- /* build the node if required */
- if (node->type->build != NULL) {
- if ((node->flags & EC_NODE_F_BUILT) == 0) {
- ret = node->type->build(node);
- if (ret < 0)
- return ret;
- }
- }
- node->flags |= EC_NODE_F_BUILT;
-
if (node->type->complete == NULL)
return -ENOTSUP;
if (ret < 0)
return ret;
-#if 0 // XXX dump
- printf("----------------------------------------------------------\n");
- ec_node_dump(stdout, node);
- ec_strvec_dump(stdout, strvec);
- ec_completed_dump(stdout, completed);
-#endif
-
return 0;
}
/* XXX ensure parent and child are properly set in all nodes */
struct ec_node *parent;
unsigned int refcnt;
-#define EC_NODE_F_BUILT 0x0001 /** set if configuration is built */
- unsigned int flags;
TAILQ_ENTRY(ec_node) next;
struct ec_node_list children;
.eval_free = ec_node_cmd_eval_free,
};
-static int
-ec_node_cmd_parse(const struct ec_node *gen_node, struct ec_parsed *state,
- const struct ec_strvec *strvec)
-{
- struct ec_node_cmd *node = (struct ec_node_cmd *)gen_node;
-
- return ec_node_parse_child(node->cmd, state, strvec);
-}
-
-static int
-ec_node_cmd_complete(const struct ec_node *gen_node,
- struct ec_completed *completed,
- const struct ec_strvec *strvec)
-{
- struct ec_node_cmd *node = (struct ec_node_cmd *)gen_node;
-
- return ec_node_complete_child(node->cmd, completed, strvec);
-}
-
-static void ec_node_cmd_free_priv(struct ec_node *gen_node)
-{
- struct ec_node_cmd *node = (struct ec_node_cmd *)gen_node;
- unsigned int i;
-
- ec_free(node->cmd_str);
- ec_node_free(node->cmd);
- ec_node_free(node->expr);
- ec_node_free(node->lex);
- for (i = 0; i < node->len; i++)
- ec_node_free(node->table[i]);
- ec_free(node->table);
-}
-
-static int ec_node_cmd_build(struct ec_node *gen_node)
+static int ec_node_cmd_build(struct ec_node_cmd *node)
{
struct ec_node *expr = NULL, *lex = NULL, *cmd = NULL;
struct ec_parsed *p, *child;
- struct ec_node_cmd *node = (struct ec_node_cmd *)gen_node;
void *result;
int ret;
- /* XXX the expr parser can be moved in the node init */
+ ec_node_free(node->expr);
+ node->expr = NULL;
+ ec_node_free(node->lex);
+ node->lex = NULL;
+ ec_node_free(node->cmd);
+ node->cmd = NULL;
/* build the expression parser */
ret = -ENOMEM;
ec_parsed_free(p);
p = NULL;
- ec_node_free(node->expr);
node->expr = expr;
- ec_node_free(node->lex);
node->lex = lex;
- ec_node_free(node->cmd);
node->cmd = cmd;
return 0;
return ret;
}
+static int
+ec_node_cmd_parse(const struct ec_node *gen_node, struct ec_parsed *state,
+ const struct ec_strvec *strvec)
+{
+ struct ec_node_cmd *node = (struct ec_node_cmd *)gen_node;
+
+ if (node->cmd == NULL)
+ return -ENOENT;
+ return ec_node_parse_child(node->cmd, state, strvec);
+}
+
+static int
+ec_node_cmd_complete(const struct ec_node *gen_node,
+ struct ec_completed *completed,
+ const struct ec_strvec *strvec)
+{
+ struct ec_node_cmd *node = (struct ec_node_cmd *)gen_node;
+
+ if (node->cmd == NULL)
+ return -ENOENT;
+ return ec_node_complete_child(node->cmd, completed, strvec);
+}
+
+static void ec_node_cmd_free_priv(struct ec_node *gen_node)
+{
+ struct ec_node_cmd *node = (struct ec_node_cmd *)gen_node;
+ unsigned int i;
+
+ ec_free(node->cmd_str);
+ ec_node_free(node->cmd);
+ ec_node_free(node->expr);
+ ec_node_free(node->lex);
+ for (i = 0; i < node->len; i++)
+ ec_node_free(node->table[i]);
+ ec_free(node->table);
+}
+
+
static struct ec_node_type ec_node_cmd_type = {
.name = "cmd",
- .build = ec_node_cmd_build,
.parse = ec_node_cmd_parse,
.complete = ec_node_cmd_complete,
.size = sizeof(struct ec_node_cmd),
{
struct ec_node_cmd *node = (struct ec_node_cmd *)gen_node;
struct ec_node **table;
+ int ret;
// XXX check node type
if (child == NULL)
return -EINVAL;
- gen_node->flags &= ~EC_NODE_F_BUILT;
+ if (node->cmd == NULL) {
+ ret = ec_node_cmd_build(node);
+ if (ret < 0)
+ return ret;
+ }
table = ec_realloc(node->table, (node->len + 1) * sizeof(*node->table));
if (table == NULL) {
return 0;
}
-struct ec_node *ec_node_cmd(const char *id, const char *cmd_str)
+struct ec_node *__ec_node_cmd(const char *id, const char *cmd, ...)
{
struct ec_node *gen_node = NULL;
struct ec_node_cmd *node = NULL;
+ struct ec_node *child;
+ va_list ap;
+ int fail = 0;
gen_node = __ec_node(&ec_node_cmd_type, id);
if (gen_node == NULL)
goto fail;
node = (struct ec_node_cmd *)gen_node;
- node->cmd_str = ec_strdup(cmd_str);
+ node->cmd_str = ec_strdup(cmd);
if (node->cmd_str == NULL)
goto fail;
- return gen_node;
-
-fail:
- ec_node_free(gen_node);
- return NULL;
-}
-
-struct ec_node *__ec_node_cmd(const char *id, const char *cmd, ...)
-{
- struct ec_node *gen_node = NULL;
- struct ec_node_cmd *node = NULL;
- struct ec_node *child;
- va_list ap;
- int fail = 0;
-
va_start(ap, cmd);
- gen_node = ec_node_cmd(id, cmd);
- node = (struct ec_node_cmd *)gen_node;
- if (node == NULL)
- fail = 1;;
-
for (child = va_arg(ap, struct ec_node *);
child != EC_NODE_ENDLIST;
child = va_arg(ap, struct ec_node *)) {
goto fail;
va_end(ap);
+
+ if (ec_node_cmd_build(node) < 0)
+ goto fail;
+
return gen_node;
fail:
return NULL;
}
+struct ec_node *ec_node_cmd(const char *id, const char *cmd_str)
+{
+ return __ec_node_cmd(id, cmd_str, EC_NODE_ENDLIST);
+}
+
/* LCOV_EXCL_START */
static int ec_node_cmd_testcase(void)
{
{
struct ec_node_expr *node = (struct ec_node_expr *)gen_node;
+ if (node->child == NULL)
+ return -ENOENT;
return ec_node_parse_child(node->child, state, strvec);
}
{
struct ec_node_expr *node = (struct ec_node_expr *)gen_node;
+ if (node->child == NULL)
+ return -ENOENT;
return ec_node_complete_child(node->child, completed, strvec);
}
ec_node_free(node->child);
}
-static int ec_node_expr_build(struct ec_node *gen_node)
+static int ec_node_expr_build(struct ec_node_expr *node)
{
- struct ec_node_expr *node = (struct ec_node_expr *)gen_node;
struct ec_node *term = NULL, *expr = NULL, *next = NULL,
*pre_op = NULL, *post_op = NULL,
*post = NULL, *weak = NULL;
unsigned int i;
int ret;
+ ec_node_free(node->child);
+ node->child = NULL;
+
if (node->val_node == NULL)
return -EINVAL;
if (node->bin_ops_len == 0 && node->pre_ops_len == 0 &&
weak = NULL;
node->child = expr;
- //ec_node_dump(stdout, node->child); //XXX
return 0;
static struct ec_node_type ec_node_expr_type = {
.name = "expr",
- .build = ec_node_expr_build,
.parse = ec_node_expr_parse,
.complete = ec_node_expr_complete,
.size = sizeof(struct ec_node_expr),
ret = -EINVAL;
if (val_node == NULL)
goto fail;
- ret = -EPERM;
- if (gen_node->flags & EC_NODE_F_BUILT)
- goto fail;
- ret = -EEXIST;
- if (node->val_node != NULL)
- goto fail;
+ ec_node_free(node->val_node);
node->val_node = val_node;
- gen_node->flags &= ~EC_NODE_F_BUILT;
+ ec_node_expr_build(node);
return 0;
ret = -EINVAL;
if (node == NULL || op == NULL)
goto fail;
- ret = -EPERM;
- if (gen_node->flags & EC_NODE_F_BUILT)
- goto fail;
ret = -ENOMEM;
bin_ops = ec_realloc(node->bin_ops,
node->bin_ops = bin_ops;
bin_ops[node->bin_ops_len] = op;
node->bin_ops_len++;
- gen_node->flags &= ~EC_NODE_F_BUILT;
+ ec_node_expr_build(node);
return 0;
ret = -EINVAL;
if (node == NULL || op == NULL)
goto fail;
- ret = -EPERM;
- if (gen_node->flags & EC_NODE_F_BUILT)
- goto fail;
ret = -ENOMEM;
pre_ops = ec_realloc(node->pre_ops,
node->pre_ops = pre_ops;
pre_ops[node->pre_ops_len] = op;
node->pre_ops_len++;
- gen_node->flags &= ~EC_NODE_F_BUILT;
+ ec_node_expr_build(node);
return 0;
ret = -EINVAL;
if (node == NULL || op == NULL)
goto fail;
- ret = -EPERM;
- if (gen_node->flags & EC_NODE_F_BUILT)
- goto fail;
ret = -ENOMEM;
post_ops = ec_realloc(node->post_ops,
node->post_ops = post_ops;
post_ops[node->post_ops_len] = op;
node->post_ops_len++;
- gen_node->flags &= ~EC_NODE_F_BUILT;
+ ec_node_expr_build(node);
return 0;
ret = -EINVAL;
if (node == NULL || open == NULL || close == NULL)
goto fail;
- ret = -EPERM;
- if (gen_node->flags & EC_NODE_F_BUILT)
- goto fail;;
ret = -ENOMEM;
open_ops = ec_realloc(node->open_ops,
open_ops[node->paren_len] = open;
close_ops[node->paren_len] = close;
node->paren_len++;
- gen_node->flags &= ~EC_NODE_F_BUILT;
+ ec_node_expr_build(node);
return 0;
return -ENOMEM;
eval->val = val;
- printf("eval var %d\n", eval->val);
+ EC_LOG(EC_LOG_DEBUG, "eval var %d\n", eval->val);
*result = eval;
return 0;
else
return -EINVAL;
- printf("eval pre_op %d\n", eval->val);
+ EC_LOG(EC_LOG_DEBUG, "eval pre_op %d\n", eval->val);
*result = eval;
return 0;
else
return -EINVAL;
- printf("eval post_op %d\n", eval->val);
+ EC_LOG(EC_LOG_DEBUG, "eval post_op %d\n", eval->val);
*result = eval;
return 0;
else
return -EINVAL;
- printf("eval bin_op %d\n", eval1->val);
+ EC_LOG(EC_LOG_DEBUG, "eval bin_op %d\n", eval1->val);
ec_free(eval2);
*result = eval1;
(void)open_paren;
(void)close_paren;
- printf("eval paren\n");
+ EC_LOG(EC_LOG_DEBUG, "eval paren\n");
*result = value;
return 0;
eval = result;
assert(eval != NULL);
- printf("result: %d (expected %d)\n", eval->val, val);
+ EC_LOG(EC_LOG_DEBUG, "result: %d (expected %d)\n", eval->val, val);
if (eval->val == val)
ret = 0;
else
p = ec_node_parse(node, "0");
s = ec_strvec_val(ec_parsed_strvec(p), 0);
- EC_TEST_ASSERT(s != NULL &&
- ec_node_int_getval(node, s, &i64) == 0 &&
- i64 == 0);
+ EC_TEST_ASSERT(s != NULL);
+ EC_TEST_ASSERT(ec_node_uint_getval(node, s, &u64) == 0);
+ EC_TEST_ASSERT (u64 == 0);
ec_parsed_free(p);
p = ec_node_parse(node, "10");
s = ec_strvec_val(ec_parsed_strvec(p), 0);
- EC_TEST_ASSERT(s != NULL &&
- ec_node_uint_getval(node, s, &u64) == 0 &&
- u64 == 10);
+ EC_TEST_ASSERT(s != NULL);
+ EC_TEST_ASSERT(ec_node_uint_getval(node, s, &u64) == 0);
+ EC_TEST_ASSERT(u64 == 10);
ec_parsed_free(p);
ec_node_free(node);
p = ec_node_parse(node, "10");
s = ec_strvec_val(ec_parsed_strvec(p), 0);
- EC_TEST_ASSERT(s != NULL &&
- ec_node_int_getval(node, s, &i64) == 0 &&
- i64 == 16);
+ EC_TEST_ASSERT(s != NULL);
+ EC_TEST_ASSERT(ec_node_int_getval(node, s, &i64) == 0);
+ EC_TEST_ASSERT(i64 == 16);
ec_parsed_free(p);
ec_node_free(node);
if (ret < 0)
return ret;
- gen_node->flags &= ~EC_NODE_F_BUILT;
-
node->child = child;
child->parent = gen_node;
if (child == NULL)
return -EINVAL;
- gen_node->flags &= ~EC_NODE_F_BUILT;
-
table = ec_realloc(node->table, (node->len + 1) * sizeof(*node->table));
if (table == NULL) {
ec_node_free(child);
if (child == NULL)
return -EINVAL;
- gen_node->flags &= ~EC_NODE_F_BUILT;
-
table = ec_realloc(node->table, (node->len + 1) * sizeof(*node->table));
if (table == NULL) {
ec_node_free(child);
new_vec = tokenize(str, 0, 0, NULL);
}
if (new_vec == NULL) {
- ret = -ENOMEM;
+ if (errno == EINVAL)
+ ret = EC_PARSED_NOMATCH;
+ else
+ ret = -ENOMEM;
goto fail;
}
if (child == NULL)
return -EINVAL;
- gen_node->flags &= ~EC_NODE_F_BUILT;
-
table = ec_realloc(node->table, (node->len + 1) * sizeof(*node->table));
if (table == NULL) {
ec_node_free(child);
if (child == NULL)
return -EINVAL;
- gen_node->flags &= ~EC_NODE_F_BUILT;
-
node->child = child;
child->parent = gen_node;
struct ec_parsed *child;
int ret;
- /* build the node if required */
- if (node->type->build != NULL) {
- if ((node->flags & EC_NODE_F_BUILT) == 0) {
- ret = node->type->build(node);
- if (ret < 0)
- return ret;
- }
- }
- node->flags |= EC_NODE_F_BUILT;
-
if (node->type->parse == NULL)
return -ENOTSUP;
}
p = ec_node_parse_strvec(tk, vec);
- ec_parsed_dump(stdout, p); /* XXX only for debug */
if (p == NULL) {
EC_LOG(EC_LOG_ERR, "parsed is NULL\n");
}
count, ec_completed_count(c, EC_COMP_FULL));
ec_completed_dump(stdout, c);
ret = -1;
- } else
- ec_completed_dump(stdout, c); //XXX
+ }
out:
ec_strvec_free(vec);