X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Fecoli_node_expr.c;h=2320c0c06dd78dc7cf208786f742a3cc9d2a5b86;hb=8c1e15f7d7e507c02f41ef9c3dbe310005ce369f;hp=b72222064ab235d4992d7c2717b10dd0bc634567;hpb=539a859dde94b304e93f44a52b7e7fc0734e3a5d;p=protos%2Flibecoli.git diff --git a/lib/ecoli_node_expr.c b/lib/ecoli_node_expr.c index b722220..2320c0c 100644 --- a/lib/ecoli_node_expr.c +++ b/lib/ecoli_node_expr.c @@ -16,12 +16,11 @@ #include #include #include -#include +#include #include #include #include #include -#include #include EC_LOG_TYPE_REGISTER(node_expr); @@ -46,13 +45,16 @@ struct ec_node_expr { }; static int ec_node_expr_parse(const struct ec_node *gen_node, - struct ec_parsed *state, + struct ec_parse *state, const struct ec_strvec *strvec) { struct ec_node_expr *node = (struct ec_node_expr *)gen_node; - if (node->child == NULL) - return -ENOENT; + if (node->child == NULL) { + errno = ENOENT; + return -1; + } + return ec_node_parse_child(node->child, state, strvec); } @@ -63,8 +65,11 @@ ec_node_expr_complete(const struct ec_node *gen_node, { struct ec_node_expr *node = (struct ec_node_expr *)gen_node; - if (node->child == NULL) - return -ENOENT; + if (node->child == NULL) { + errno = ENOENT; + return -1; + } + return ec_node_complete_child(node->child, comp, strvec); } @@ -91,26 +96,28 @@ static void ec_node_expr_free_priv(struct ec_node *gen_node) } ec_free(node->open_ops); ec_free(node->close_ops); - - ec_node_free(node->child); } static int ec_node_expr_build(struct ec_node_expr *node) { struct ec_node *term = NULL, *expr = NULL, *next = NULL, - *pre_op = NULL, *post_op = NULL, - *post = NULL, *weak = NULL; + *pre_op = NULL, *post_op = NULL, *ref = NULL, + *post = NULL; unsigned int i; - int ret; ec_node_free(node->child); node->child = NULL; - if (node->val_node == NULL) - return -EINVAL; + if (node->val_node == NULL) { + errno = EINVAL; + return -1; + } + if (node->bin_ops_len == 0 && node->pre_ops_len == 0 && - node->post_ops_len == 0) - return -EINVAL; + node->post_ops_len == 0) { + errno = EINVAL; + return -1; + } /* * Example of created grammar: @@ -126,11 +133,9 @@ static int ec_node_expr_build(struct ec_node_expr *node) * expr = sum */ - /* create the object, we will initialize it later: this is - * needed because we have a circular dependency */ - ret = -ENOMEM; - weak = ec_node("weakref", "weak"); - if (weak == NULL) + /* we use this as a ref, will be set later */ + ref = ec_node("seq", "ref"); + if (ref == NULL) return -1; /* prefix unary operators */ @@ -159,12 +164,12 @@ static int ec_node_expr_build(struct ec_node_expr *node) if (ec_node_or_add(post, EC_NODE_SEQ(EC_NO_ID, ec_node_clone(pre_op), - ec_node_clone(weak))) < 0) + ec_node_clone(ref))) < 0) goto fail; for (i = 0; i < node->paren_len; i++) { if (ec_node_or_add(post, EC_NODE_SEQ(EC_NO_ID, ec_node_clone(node->open_ops[i]), - ec_node_clone(weak), + ec_node_clone(ref), ec_node_clone(node->close_ops[i]))) < 0) goto fail; } @@ -202,11 +207,10 @@ static int ec_node_expr_build(struct ec_node_expr *node) ec_node_free(post); post = NULL; - /* no need to clone here, the node is not consumed */ - if (ec_node_weakref_set(weak, expr) < 0) + if (ec_node_seq_add(ref, ec_node_clone(expr)) < 0) goto fail; - ec_node_free(weak); - weak = NULL; + ec_node_free(ref); + ref = NULL; node->child = expr; @@ -218,9 +222,30 @@ fail: ec_node_free(pre_op); ec_node_free(post_op); ec_node_free(post); - ec_node_free(weak); + ec_node_free(ref); + + return -1; +} + +static size_t +ec_node_expr_get_children_count(const struct ec_node *gen_node) +{ + struct ec_node_expr *node = (struct ec_node_expr *)gen_node; + + if (node->child) + return 1; + return 0; +} - return ret; +static struct ec_node * +ec_node_expr_get_child(const struct ec_node *gen_node, size_t i) +{ + struct ec_node_expr *node = (struct ec_node_expr *)gen_node; + + if (i >= 1) + return NULL; + + return node->child; } static struct ec_node_type ec_node_expr_type = { @@ -229,6 +254,8 @@ static struct ec_node_type ec_node_expr_type = { .complete = ec_node_expr_complete, .size = sizeof(struct ec_node_expr), .free_priv = ec_node_expr_free_priv, + .get_children_count = ec_node_expr_get_children_count, + .get_child = ec_node_expr_get_child, }; EC_NODE_TYPE_REGISTER(ec_node_expr_type); @@ -236,15 +263,14 @@ EC_NODE_TYPE_REGISTER(ec_node_expr_type); int ec_node_expr_set_val_node(struct ec_node *gen_node, struct ec_node *val_node) { struct ec_node_expr *node = (struct ec_node_expr *)gen_node; - int ret; - ret = ec_node_check_type(gen_node, &ec_node_expr_type); - if (ret < 0) - return ret; + if (ec_node_check_type(gen_node, &ec_node_expr_type) < 0) + goto fail; - ret = -EINVAL; - if (val_node == NULL) + if (val_node == NULL) { + errno = EINVAL; goto fail; + } ec_node_free(node->val_node); node->val_node = val_node; @@ -254,7 +280,7 @@ int ec_node_expr_set_val_node(struct ec_node *gen_node, struct ec_node *val_node fail: ec_node_free(val_node); - return ret; + return -1; } /* add a binary operator */ @@ -262,17 +288,15 @@ int ec_node_expr_add_bin_op(struct ec_node *gen_node, struct ec_node *op) { struct ec_node_expr *node = (struct ec_node_expr *)gen_node; struct ec_node **bin_ops; - int ret; - ret = ec_node_check_type(gen_node, &ec_node_expr_type); - if (ret < 0) - return ret; + if (ec_node_check_type(gen_node, &ec_node_expr_type) < 0) + goto fail; - ret = -EINVAL; - if (node == NULL || op == NULL) + if (node == NULL || op == NULL) { + errno = EINVAL; goto fail; + } - ret = -ENOMEM; bin_ops = ec_realloc(node->bin_ops, (node->bin_ops_len + 1) * sizeof(*node->bin_ops)); if (bin_ops == NULL) @@ -287,7 +311,7 @@ int ec_node_expr_add_bin_op(struct ec_node *gen_node, struct ec_node *op) fail: ec_node_free(op); - return ret; + return -1; } /* add a unary pre-operator */ @@ -295,17 +319,15 @@ int ec_node_expr_add_pre_op(struct ec_node *gen_node, struct ec_node *op) { struct ec_node_expr *node = (struct ec_node_expr *)gen_node; struct ec_node **pre_ops; - int ret; - ret = ec_node_check_type(gen_node, &ec_node_expr_type); - if (ret < 0) - return ret; + if (ec_node_check_type(gen_node, &ec_node_expr_type) < 0) + goto fail; - ret = -EINVAL; - if (node == NULL || op == NULL) + if (node == NULL || op == NULL) { + errno = EINVAL; goto fail; + } - ret = -ENOMEM; pre_ops = ec_realloc(node->pre_ops, (node->pre_ops_len + 1) * sizeof(*node->pre_ops)); if (pre_ops == NULL) @@ -320,7 +342,7 @@ int ec_node_expr_add_pre_op(struct ec_node *gen_node, struct ec_node *op) fail: ec_node_free(op); - return ret; + return -1; } /* add a unary post-operator */ @@ -328,17 +350,15 @@ int ec_node_expr_add_post_op(struct ec_node *gen_node, struct ec_node *op) { struct ec_node_expr *node = (struct ec_node_expr *)gen_node; struct ec_node **post_ops; - int ret; - ret = ec_node_check_type(gen_node, &ec_node_expr_type); - if (ret < 0) - return ret; + if (ec_node_check_type(gen_node, &ec_node_expr_type) < 0) + goto fail; - ret = -EINVAL; - if (node == NULL || op == NULL) + if (node == NULL || op == NULL) { + errno = EINVAL; goto fail; + } - ret = -ENOMEM; post_ops = ec_realloc(node->post_ops, (node->post_ops_len + 1) * sizeof(*node->post_ops)); if (post_ops == NULL) @@ -353,7 +373,7 @@ int ec_node_expr_add_post_op(struct ec_node *gen_node, struct ec_node *op) fail: ec_node_free(op); - return ret; + return -1; } /* add parenthesis symbols */ @@ -362,17 +382,15 @@ int ec_node_expr_add_parenthesis(struct ec_node *gen_node, { struct ec_node_expr *node = (struct ec_node_expr *)gen_node; struct ec_node **open_ops, **close_ops; - int ret; - ret = ec_node_check_type(gen_node, &ec_node_expr_type); - if (ret < 0) - return ret; + if (ec_node_check_type(gen_node, &ec_node_expr_type) < 0) + goto fail; - ret = -EINVAL; - if (node == NULL || open == NULL || close == NULL) + if (node == NULL || open == NULL || close == NULL) { + errno = EINVAL; goto fail; + } - ret = -ENOMEM; open_ops = ec_realloc(node->open_ops, (node->paren_len + 1) * sizeof(*node->open_ops)); if (open_ops == NULL) @@ -394,7 +412,7 @@ int ec_node_expr_add_parenthesis(struct ec_node *gen_node, fail: ec_node_free(open); ec_node_free(close); - return ret; + return -1; } enum expr_node_type { @@ -444,7 +462,7 @@ static enum expr_node_type get_node_type(const struct ec_node *expr_gen_node, struct result { bool has_val; void *val; - const struct ec_parsed *op; + const struct ec_parse *op; enum expr_node_type op_type; }; @@ -453,8 +471,6 @@ static int merge_results(void *userctx, const struct ec_node_expr_eval_ops *ops, struct result *x, const struct result *y) { - int ret; - if (y->has_val == 0 && y->op == NULL) return 0; if (x->has_val == 0 && x->op == NULL) { @@ -464,10 +480,9 @@ static int merge_results(void *userctx, if (x->has_val && y->has_val && y->op != NULL) { if (y->op_type == BIN_OP) { - ret = ops->eval_bin_op(&x->val, userctx, x->val, - y->op, y->val); - if (ret < 0) - return ret; + if (ops->eval_bin_op(&x->val, userctx, x->val, + y->op, y->val) < 0) + return -1; return 0; } @@ -475,9 +490,9 @@ static int merge_results(void *userctx, if (x->has_val == 0 && x->op != NULL && y->has_val && y->op == NULL) { if (x->op_type == PRE_OP) { - ret = ops->eval_pre_op(&x->val, userctx, y->val, x->op); - if (ret < 0) - return ret; + if (ops->eval_pre_op(&x->val, userctx, y->val, + x->op) < 0) + return -1; x->has_val = true; x->op_type = NONE; x->op = NULL; @@ -490,47 +505,44 @@ static int merge_results(void *userctx, } if (x->has_val && x->op == NULL && y->has_val == 0 && y->op != NULL) { - ret = ops->eval_post_op(&x->val, userctx, x->val, y->op); - if (ret < 0) - return ret; + if (ops->eval_post_op(&x->val, userctx, x->val, y->op) < 0) + return -1; return 0; } assert(false); /* we should not get here */ - return -EINVAL; + return -1; } static int eval_expression(struct result *result, void *userctx, const struct ec_node_expr_eval_ops *ops, const struct ec_node *expr_gen_node, - const struct ec_parsed *parsed) + const struct ec_parse *parse) { - struct ec_parsed *open = NULL, *close = NULL; + struct ec_parse *open = NULL, *close = NULL; struct result child_result; - struct ec_parsed *child; + struct ec_parse *child; enum expr_node_type type; - int ret; memset(result, 0, sizeof(*result)); memset(&child_result, 0, sizeof(child_result)); - type = get_node_type(expr_gen_node, ec_parsed_get_node(parsed)); + type = get_node_type(expr_gen_node, ec_parse_get_node(parse)); if (type == VAL) { - ret = ops->eval_var(&result->val, userctx, parsed); - if (ret < 0) + if (ops->eval_var(&result->val, userctx, parse) < 0) goto fail; result->has_val = 1; } else if (type == PRE_OP || type == POST_OP || type == BIN_OP) { - result->op = parsed; + result->op = parse; result->op_type = type; } - EC_PARSED_FOREACH_CHILD(child, parsed) { + EC_PARSE_FOREACH_CHILD(child, parse) { - type = get_node_type(expr_gen_node, ec_parsed_get_node(child)); + type = get_node_type(expr_gen_node, ec_parse_get_node(child)); if (type == PAREN_OPEN) { open = child; continue; @@ -539,22 +551,19 @@ static int eval_expression(struct result *result, continue; } - ret = eval_expression(&child_result, userctx, ops, - expr_gen_node, child); - if (ret < 0) + if (eval_expression(&child_result, userctx, ops, + expr_gen_node, child) < 0) goto fail; - ret = merge_results(userctx, ops, result, &child_result); - if (ret < 0) + if (merge_results(userctx, ops, result, &child_result) < 0) goto fail; memset(&child_result, 0, sizeof(child_result)); } if (open != NULL && close != NULL) { - ret = ops->eval_parenthesis(&result->val, userctx, open, close, - result->val); - if (ret < 0) + if (ops->eval_parenthesis(&result->val, userctx, open, close, + result->val) < 0) goto fail; } @@ -567,31 +576,33 @@ fail: ops->eval_free(child_result.val, userctx); memset(result, 0, sizeof(*result)); - return ret; + return -1; } int ec_node_expr_eval(void **user_result, const struct ec_node *node, - struct ec_parsed *parsed, const struct ec_node_expr_eval_ops *ops, + struct ec_parse *parse, const struct ec_node_expr_eval_ops *ops, void *userctx) { struct result result; - int ret; if (ops == NULL || ops->eval_var == NULL || ops->eval_pre_op == NULL || ops->eval_post_op == NULL || ops->eval_bin_op == NULL || - ops->eval_parenthesis == NULL || ops->eval_free == NULL) - return -EINVAL; + ops->eval_parenthesis == NULL || + ops->eval_free == NULL) { + errno = EINVAL; + return -1; + } - ret = ec_node_check_type(node, &ec_node_expr_type); - if (ret < 0) - return ret; + if (ec_node_check_type(node, &ec_node_expr_type) < 0) + return -1; - if (!ec_parsed_matches(parsed)) - return -EINVAL; + if (!ec_parse_matches(parse)) { + errno = EINVAL; + return -1; + } - ret = eval_expression(&result, userctx, ops, node, parsed); - if (ret < 0) - return ret; + if (eval_expression(&result, userctx, ops, node, parse) < 0) + return -1; assert(result.has_val); assert(result.op == NULL);