standardize return values + errno
authorOlivier Matz <zer0@droids-corp.org>
Sun, 18 Mar 2018 21:39:47 +0000 (22:39 +0100)
committerOlivier Matz <zer0@droids-corp.org>
Sun, 18 Mar 2018 21:39:47 +0000 (22:39 +0100)
21 files changed:
lib/Makefile
lib/ecoli_assert.h
lib/ecoli_complete.c
lib/ecoli_node.c
lib/ecoli_node_cmd.c
lib/ecoli_node_expr.c
lib/ecoli_node_expr_test.c
lib/ecoli_node_int.c
lib/ecoli_node_many.c
lib/ecoli_node_re.c
lib/ecoli_node_re_lex.c
lib/ecoli_node_seq.c
lib/ecoli_node_sh_lex.c
lib/ecoli_node_str.c
lib/ecoli_node_subset.c
lib/ecoli_parse.c
lib/ecoli_parse.h
lib/ecoli_strvec.c
lib/ecoli_vec.c
lib/main-readline.c
lib/todo.txt

index e033dd8..b97f619 100644 (file)
@@ -8,7 +8,7 @@ include $(ECOLI)/mk/ecoli-pre.mk
 O ?= build/
 
 # XXX -O0
-CFLAGS  = -g -O0 -Wall -Werror -W -Wextra -fPIC -Wmissing-prototypes
+CFLAGS  = -g -O3 -Wall -Werror -W -Wextra -fPIC -Wmissing-prototypes
 CFLAGS += -I.
 
 # XXX coverage
index b1ef0ec..fcd2186 100644 (file)
@@ -5,8 +5,8 @@
 /**
  * Assert API
  *
- * Helpers to check at runtime if a condition is true, and abort
- * (exit) otherwise.
+ * Helpers to check at runtime if a condition is true, or otherwise
+ * either abort (exit program) or return an error.
  */
 
 #ifndef ECOLI_ASSERT_
 void __ec_assert_print(bool expr, const char *expr_str,
                const char *format, ...);
 
+/**
+ * Check a condition or return.
+ *
+ * If the condition is true, do nothing. If it is false, set
+ * errno and return the specified value.
+ *
+ * @param cond
+ *   The condition to test.
+ * @param ret
+ *   The value to return.
+ * @param err
+ *   The errno to set.
+ */
+#define EC_CHECK_ARG(cond, ret, err) do {                              \
+               if (!(cond)) {                                          \
+                       errno = err;                                    \
+                       return ret;                                     \
+               }                                                       \
+       } while(0)
+
 #endif
index cbe51b2..815b825 100644 (file)
@@ -74,14 +74,16 @@ ec_node_complete_child(const struct ec_node *node,
        struct ec_comp_group *cur_group;
        int ret;
 
-       if (ec_node_type(node)->complete == NULL)
-               return -ENOTSUP;
+       if (ec_node_type(node)->complete == NULL) {
+               errno = ENOTSUP;
+               return -1;
+       }
 
        /* save previous parse state, prepare child state */
        cur_state = comp->cur_state;
        child_state = ec_parse(node);
        if (child_state == NULL)
-               return -ENOMEM;
+               return -1;
 
        if (cur_state != NULL)
                ec_parse_link_child(cur_state, child_state);
@@ -102,7 +104,7 @@ ec_node_complete_child(const struct ec_node *node,
        comp->cur_group = cur_group;
 
        if (ret < 0)
-               return ret;
+               return -1;
 
        return 0;
 }
@@ -255,11 +257,12 @@ int ec_comp_item_set_display(struct ec_comp_item *item,
                                const char *display)
 {
        char *display_copy = NULL;
-       int ret = 0;
 
        if (item == NULL || display == NULL ||
-                       item->type == EC_COMP_UNKNOWN)
-               return -EINVAL;
+                       item->type == EC_COMP_UNKNOWN) {
+               errno = EINVAL;
+               return -1;
+       }
 
        display_copy = ec_strdup(display);
        if (display_copy == NULL)
@@ -272,7 +275,7 @@ int ec_comp_item_set_display(struct ec_comp_item *item,
 
 fail:
        ec_free(display_copy);
-       return ret;
+       return -1;
 }
 
 int
@@ -280,13 +283,13 @@ ec_comp_item_set_completion(struct ec_comp_item *item,
                                const char *completion)
 {
        char *completion_copy = NULL;
-       int ret = 0;
 
        if (item == NULL || completion == NULL ||
-                       item->type == EC_COMP_UNKNOWN)
-               return -EINVAL;
+                       item->type == EC_COMP_UNKNOWN) {
+               errno = EINVAL;
+               return -1;
+       }
 
-       ret = -ENOMEM;
        completion_copy = ec_strdup(completion);
        if (completion_copy == NULL)
                goto fail;
@@ -298,7 +301,7 @@ ec_comp_item_set_completion(struct ec_comp_item *item,
 
 fail:
        ec_free(completion_copy);
-       return ret;
+       return -1;
 }
 
 int
@@ -306,13 +309,13 @@ ec_comp_item_set_str(struct ec_comp_item *item,
                        const char *str)
 {
        char *str_copy = NULL;
-       int ret = 0;
 
        if (item == NULL || str == NULL ||
-                       item->type == EC_COMP_UNKNOWN)
-               return -EINVAL;
+                       item->type == EC_COMP_UNKNOWN) {
+               errno = EINVAL;
+               return -1;
+       }
 
-       ret = -ENOMEM;
        str_copy = ec_strdup(str);
        if (str_copy == NULL)
                goto fail;
@@ -324,15 +327,17 @@ ec_comp_item_set_str(struct ec_comp_item *item,
 
 fail:
        ec_free(str_copy);
-       return ret;
+       return -1;
 }
 
 static int
 ec_comp_item_add(struct ec_comp *comp, const struct ec_node *node,
                struct ec_comp_item *item)
 {
-       if (comp == NULL || item == NULL)
-               return -EINVAL;
+       if (comp == NULL || item == NULL) {
+               errno = EINVAL;
+               return -1;
+       }
 
        switch (item->type) {
        case EC_COMP_UNKNOWN:
@@ -345,7 +350,8 @@ ec_comp_item_add(struct ec_comp *comp, const struct ec_node *node,
                comp->count_partial++;
                break;
        default:
-               return -EINVAL;
+               errno = EINVAL;
+               return -1;
        }
 
        if (comp->cur_group == NULL) {
@@ -353,7 +359,7 @@ ec_comp_item_add(struct ec_comp *comp, const struct ec_node *node,
 
                grp = ec_comp_group(node, comp->cur_state);
                if (grp == NULL)
-                       return -ENOMEM;
+                       return -1;
                TAILQ_INSERT_TAIL(&comp->groups, grp, next);
                comp->cur_group = grp;
        }
index 4360336..bf57238 100644 (file)
@@ -35,15 +35,18 @@ ec_node_type_lookup(const char *name)
                        return type;
        }
 
+       errno = ENOENT;
        return NULL;
 }
 
 int ec_node_type_register(struct ec_node_type *type)
 {
-       if (ec_node_type_lookup(type->name) != NULL)
-               return -EEXIST;
-       if (type->size < sizeof(struct ec_node))
-               return -EINVAL;
+       EC_CHECK_ARG(type->size >= sizeof(struct ec_node), -1, EINVAL);
+
+       if (ec_node_type_lookup(type->name) != NULL) {
+               errno = EEXIST;
+               return -1;
+       }
 
        TAILQ_INSERT_TAIL(&node_type_list, type, next);
 
@@ -182,6 +185,7 @@ int ec_node_add_child(struct ec_node *node, struct ec_node *child)
 
 fail:
        ec_free(children);
+       assert(errno != 0);
        return -1;
 }
 
@@ -289,6 +293,7 @@ int ec_node_check_type(const struct ec_node *node,
                errno = EINVAL;
                return -1;
        }
+
        return 0;
 }
 
@@ -393,6 +398,7 @@ fail:
                fclose(f);
        free(buf);
 
+       assert(errno != 0);
        return -1;
 }
 /* LCOV_EXCL_STOP */
index 64242e6..99a7732 100644 (file)
@@ -56,8 +56,10 @@ ec_node_cmd_eval_var(void **result, void *userctx,
 
        /* get parsed string vector, it should contain only one str */
        vec = ec_parse_strvec(var);
-       if (ec_strvec_len(vec) != 1)
-               return -EINVAL;
+       if (ec_strvec_len(vec) != 1) {
+               errno = EINVAL;
+               return -1;
+       }
        str = ec_strvec_val(vec, 0);
 
        for (i = 0; i < node->len; i++) {
@@ -69,7 +71,7 @@ ec_node_cmd_eval_var(void **result, void *userctx,
                /* if id matches, use a node provided by the user... */
                eval = ec_node_clone(node->table[i]);
                if (eval == NULL)
-                       return -ENOMEM;
+                       return -1;
                break;
        }
 
@@ -77,7 +79,7 @@ ec_node_cmd_eval_var(void **result, void *userctx,
        if (eval == NULL) {
                eval = ec_node_str(EC_NO_ID, str);
                if (eval == NULL)
-                       return -ENOMEM;
+                       return -1;
        }
 
        *result = eval;
@@ -94,7 +96,8 @@ ec_node_cmd_eval_pre_op(void **result, void *userctx, void *operand,
        (void)operand;
        (void)operator;
 
-       return -EINVAL;
+       errno = EINVAL;
+       return -1;
 }
 
 static int
@@ -109,18 +112,21 @@ ec_node_cmd_eval_post_op(void **result, void *userctx, void *operand,
 
        /* get parsed string vector, it should contain only one str */
        vec = ec_parse_strvec(operator);
-       if (ec_strvec_len(vec) != 1)
-               return -EINVAL;
+       if (ec_strvec_len(vec) != 1) {
+               errno = EINVAL;
+               return -1;
+       }
 
        if (!strcmp(ec_strvec_val(vec, 0), "*")) {
                out = ec_node_many(EC_NO_ID,
                                ec_node_clone(in), 0, 0);
                if (out == NULL)
-                       return -EINVAL;
+                       return -1;
                ec_node_free(in);
                *result = out;
        } else {
-               return -EINVAL;
+               errno = EINVAL;
+               return -1;
        }
 
        return 0;
@@ -140,20 +146,22 @@ ec_node_cmd_eval_bin_op(void **result, void *userctx, void *operand1,
 
        /* get parsed string vector, it should contain only one str */
        vec = ec_parse_strvec(operator);
-       if (ec_strvec_len(vec) > 1)
-               return -EINVAL;
+       if (ec_strvec_len(vec) > 1) {
+               errno = EINVAL;
+               return -1;
+       }
 
        if (ec_strvec_len(vec) == 0) {
                if (!strcmp(in1->type->name, "seq")) {
                        if (ec_node_seq_add(in1, ec_node_clone(in2)) < 0)
-                               return -EINVAL;
+                               return -1;
                        ec_node_free(in2);
                        *result = in1;
                } else {
                        out = EC_NODE_SEQ(EC_NO_ID, ec_node_clone(in1),
                                        ec_node_clone(in2));
                        if (out == NULL)
-                               return -EINVAL;
+                               return -1;
                        ec_node_free(in1);
                        ec_node_free(in2);
                        *result = out;
@@ -161,19 +169,19 @@ ec_node_cmd_eval_bin_op(void **result, void *userctx, void *operand1,
        } else if (!strcmp(ec_strvec_val(vec, 0), "|")) {
                if (!strcmp(in2->type->name, "or")) {
                        if (ec_node_or_add(in2, ec_node_clone(in1)) < 0)
-                               return -EINVAL;
+                               return -1;
                        ec_node_free(in1);
                        *result = in2;
                } else if (!strcmp(in1->type->name, "or")) {
                        if (ec_node_or_add(in1, ec_node_clone(in2)) < 0)
-                               return -EINVAL;
+                               return -1;
                        ec_node_free(in2);
                        *result = in1;
                } else {
                        out = EC_NODE_OR(EC_NO_ID, ec_node_clone(in1),
                                        ec_node_clone(in2));
                        if (out == NULL)
-                               return -EINVAL;
+                               return -1;
                        ec_node_free(in1);
                        ec_node_free(in2);
                        *result = out;
@@ -181,25 +189,26 @@ ec_node_cmd_eval_bin_op(void **result, void *userctx, void *operand1,
        } else if (!strcmp(ec_strvec_val(vec, 0), ",")) {
                if (!strcmp(in2->type->name, "subset")) {
                        if (ec_node_subset_add(in2, ec_node_clone(in1)) < 0)
-                               return -EINVAL;
+                               return -1;
                        ec_node_free(in1);
                        *result = in2;
                } else if (!strcmp(in1->type->name, "subset")) {
                        if (ec_node_subset_add(in1, ec_node_clone(in2)) < 0)
-                               return -EINVAL;
+                               return -1;
                        ec_node_free(in2);
                        *result = in1;
                } else {
                        out = EC_NODE_SUBSET(EC_NO_ID, ec_node_clone(in1),
                                        ec_node_clone(in2));
                        if (out == NULL)
-                               return -EINVAL;
+                               return -1;
                        ec_node_free(in1);
                        ec_node_free(in2);
                        *result = out;
                }
        } else {
-               return -EINVAL;
+               errno = EINVAL;
+               return -1;
        }
 
        return 0;
@@ -220,18 +229,21 @@ ec_node_cmd_eval_parenthesis(void **result, void *userctx,
 
        /* get parsed string vector, it should contain only one str */
        vec = ec_parse_strvec(open_paren);
-       if (ec_strvec_len(vec) != 1)
-               return -EINVAL;
+       if (ec_strvec_len(vec) != 1) {
+               errno = EINVAL;
+               return -1;
+       }
 
        if (!strcmp(ec_strvec_val(vec, 0), "[")) {
                out = ec_node_option(EC_NO_ID, ec_node_clone(in));
                if (out == NULL)
-                       return -EINVAL;
+                       return -1;
                ec_node_free(in);
        } else if (!strcmp(ec_strvec_val(vec, 0), "(")) {
                out = in;
        } else {
-               return -EINVAL;
+               errno = EINVAL;
+               return -1;
        }
 
        *result = out;
@@ -270,11 +282,11 @@ static int ec_node_cmd_build(struct ec_node_cmd *node)
        node->cmd = NULL;
 
        /* build the expression parser */
-       ret = -ENOMEM;
        expr = ec_node("expr", "expr");
        if (expr == NULL)
                goto fail;
-       ret = ec_node_expr_set_val_node(expr, ec_node_re(EC_NO_ID, "[a-zA-Z0-9]+"));
+       ret = ec_node_expr_set_val_node(expr, ec_node_re(EC_NO_ID,
+                                       "[a-zA-Z0-9]+"));
        if (ret < 0)
                goto fail;
        ret = ec_node_expr_add_bin_op(expr, ec_node_str(EC_NO_ID, ","));
@@ -302,7 +314,6 @@ static int ec_node_cmd_build(struct ec_node_cmd *node)
                goto fail;
 
        /* prepend a lexer to the expression node */
-       ret = -ENOMEM;
        lex = ec_node_re_lex(EC_NO_ID, ec_node_clone(expr));
        if (lex == NULL)
                goto fail;
@@ -324,16 +335,18 @@ static int ec_node_cmd_build(struct ec_node_cmd *node)
                goto fail;
 
        /* parse the command expression */
-       ret = -ENOMEM;
        p = ec_node_parse(lex, node->cmd_str);
        if (p == NULL)
                goto fail;
 
-       ret = -EINVAL;
-       if (!ec_parse_matches(p))
+       if (!ec_parse_matches(p)) {
+               errno = EINVAL;
                goto fail;
-       if (!ec_parse_has_child(p))
+       }
+       if (!ec_parse_has_child(p)) {
+               errno = EINVAL;
                goto fail;
+       }
 
        ret = ec_node_expr_eval(&result, expr, ec_parse_get_first_child(p),
                                &test_ops, node);
@@ -354,7 +367,8 @@ fail:
        ec_node_free(expr);
        ec_node_free(lex);
        ec_node_free(cmd);
-       return ret;
+
+       return -1;
 }
 
 static int
@@ -363,8 +377,6 @@ ec_node_cmd_parse(const struct ec_node *gen_node, struct ec_parse *state,
 {
        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);
 }
 
@@ -375,8 +387,6 @@ ec_node_cmd_complete(const struct ec_node *gen_node,
 {
        struct ec_node_cmd *node = (struct ec_node_cmd *)gen_node;
 
-       if (node->cmd == NULL)
-               return -ENOENT;
        return ec_node_complete_child(node->cmd, comp, strvec);
 }
 
index 8a0d319..41a14bb 100644 (file)
@@ -51,8 +51,11 @@ static int ec_node_expr_parse(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_parse_child(node->child, state, strvec);
 }
 
@@ -63,8 +66,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);
 }
 
@@ -101,16 +107,20 @@ static int ec_node_expr_build(struct ec_node_expr *node)
                *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->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:
@@ -128,7 +138,6 @@ static int ec_node_expr_build(struct ec_node_expr *node)
 
        /* 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)
                return -1;
@@ -220,7 +229,7 @@ fail:
        ec_node_free(post);
        ec_node_free(weak);
 
-       return ret;
+       return -1;
 }
 
 static struct ec_node_type ec_node_expr_type = {
@@ -236,15 +245,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 +262,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 +270,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 +293,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 +301,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 +324,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 +332,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 +355,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 +364,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 +394,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 {
@@ -453,8 +453,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 +462,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 +472,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,15 +487,14 @@ 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,
@@ -512,15 +508,13 @@ static int eval_expression(struct result *result,
        struct result child_result;
        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_parse_get_node(parse));
        if (type == VAL) {
-               ret = ops->eval_var(&result->val, userctx, parse);
-               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) {
@@ -539,22 +533,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,7 +558,7 @@ 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,
@@ -575,23 +566,25 @@ int ec_node_expr_eval(void **user_result, const struct ec_node *node,
        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_parse_matches(parse))
-               return -EINVAL;
+       if (!ec_parse_matches(parse)) {
+               errno = EINVAL;
+               return -1;
+       }
 
-       ret = eval_expression(&result, userctx, ops, node, parse);
-       if (ret < 0)
-               return ret;
+       if (eval_expression(&result, userctx, ops, node, parse) < 0)
+               return -1;
 
        assert(result.has_val);
        assert(result.op == NULL);
index 2c9d58e..93e33a4 100644 (file)
@@ -36,16 +36,18 @@ ec_node_expr_test_eval_var(void **result, void *userctx,
 
        /* get parsed string vector, it should contain only one str */
        vec = ec_parse_strvec(var);
-       if (ec_strvec_len(vec) != 1)
-               return -EINVAL;
+       if (ec_strvec_len(vec) != 1) {
+               errno = EINVAL;
+               return -1;
+       }
 
        node = ec_parse_get_node(var);
        if (ec_node_int_getval(node, ec_strvec_val(vec, 0), &val) < 0)
-               return -EINVAL;
+               return -1;
 
        eval = ec_malloc(sizeof(*eval));
        if (eval == NULL)
-               return -ENOMEM;
+               return -1;
 
        eval->val = val;
        EC_LOG(EC_LOG_DEBUG, "eval var %d\n", eval->val);
@@ -65,13 +67,18 @@ ec_node_expr_test_eval_pre_op(void **result, void *userctx, void *operand,
 
        /* get parsed string vector, it should contain only one str */
        vec = ec_parse_strvec(operator);
-       if (ec_strvec_len(vec) != 1)
-               return -EINVAL;
+       if (ec_strvec_len(vec) != 1) {
+               errno = EINVAL;
+               return -1;
+       }
 
-       if (!strcmp(ec_strvec_val(vec, 0), "!"))
+       if (!strcmp(ec_strvec_val(vec, 0), "!")) {
                eval->val = !eval->val;
-       else
-               return -EINVAL;
+       } else {
+               errno = EINVAL;
+               return -1;
+       }
+
 
        EC_LOG(EC_LOG_DEBUG, "eval pre_op %d\n", eval->val);
        *result = eval;
@@ -90,13 +97,17 @@ ec_node_expr_test_eval_post_op(void **result, void *userctx, void *operand,
 
        /* get parsed string vector, it should contain only one str */
        vec = ec_parse_strvec(operator);
-       if (ec_strvec_len(vec) != 1)
-               return -EINVAL;
+       if (ec_strvec_len(vec) != 1) {
+               errno = EINVAL;
+               return -1;
+       }
 
-       if (!strcmp(ec_strvec_val(vec, 0), "^"))
+       if (!strcmp(ec_strvec_val(vec, 0), "^")) {
                eval->val = eval->val * eval->val;
-       else
-               return -EINVAL;
+       } else {
+               errno = EINVAL;
+               return -1;
+       }
 
        EC_LOG(EC_LOG_DEBUG, "eval post_op %d\n", eval->val);
        *result = eval;
@@ -117,15 +128,19 @@ ec_node_expr_test_eval_bin_op(void **result, void *userctx, void *operand1,
 
        /* get parsed string vector, it should contain only one str */
        vec = ec_parse_strvec(operator);
-       if (ec_strvec_len(vec) != 1)
-               return -EINVAL;
+       if (ec_strvec_len(vec) != 1) {
+               errno = EINVAL;
+               return -1;
+       }
 
-       if (!strcmp(ec_strvec_val(vec, 0), "+"))
+       if (!strcmp(ec_strvec_val(vec, 0), "+")) {
                eval1->val = eval1->val + eval2->val;
-       else if (!strcmp(ec_strvec_val(vec, 0), "*"))
+       } else if (!strcmp(ec_strvec_val(vec, 0), "*")) {
                eval1->val = eval1->val * eval2->val;
-       else
-               return -EINVAL;
+       } else {
+               errno = EINVAL;
+               return -1;
+       }
 
        EC_LOG(EC_LOG_DEBUG, "eval bin_op %d\n", eval1->val);
        ec_free(eval2);
index 2e1f2a2..34fd501 100644 (file)
@@ -51,14 +51,20 @@ static int parse_llint(struct ec_node_int_uint *node, const char *str,
                        (errno != 0 && *val == 0))
                return -1;
 
-       if (node->check_min && *val < node->min)
+       if (node->check_min && *val < node->min) {
+               errno = ERANGE;
                return -1;
+       }
 
-       if (node->check_max && *val > node->max)
+       if (node->check_max && *val > node->max) {
+               errno = ERANGE;
                return -1;
+       }
 
-       if (*endptr != 0)
+       if (*endptr != 0) {
+               errno = EINVAL;
                return -1;
+       }
 
        return 0;
 }
index 7748045..69e8e6c 100644 (file)
@@ -42,10 +42,8 @@ static int ec_node_many_parse(const struct ec_node *gen_node,
        for (count = 0; node->max == 0 || count < node->max; count++) {
                childvec = ec_strvec_ndup(strvec, off,
                        ec_strvec_len(strvec) - off);
-               if (childvec == NULL) {
-                       ret = -ENOMEM;
+               if (childvec == NULL)
                        goto fail;
-               }
 
                ret = ec_node_parse_child(node->child, state, childvec);
                if (ret < 0)
@@ -77,7 +75,7 @@ static int ec_node_many_parse(const struct ec_node *gen_node,
 
 fail:
        ec_strvec_free(childvec);
-       return ret;
+       return -1;
 }
 
 static int
index ee381d2..05db048 100644 (file)
@@ -75,17 +75,20 @@ int ec_node_re_set_regexp(struct ec_node *gen_node, const char *str)
        regex_t re;
        int ret;
 
-       if (str == NULL)
-               return -EINVAL;
+       EC_CHECK_ARG(str != NULL, -1, EINVAL);
 
-       ret = -ENOMEM;
        str_copy = ec_strdup(str);
        if (str_copy == NULL)
                goto fail;
 
-       ret = -EINVAL;
-       if (regcomp(&re, str_copy, REG_EXTENDED) != 0)
+       ret = regcomp(&re, str_copy, REG_EXTENDED);
+       if (ret != 0) {
+               if (ret == REG_ESPACE)
+                       errno = ENOMEM;
+               else
+                       errno = EINVAL;
                goto fail;
+       }
 
        if (node->re_str != NULL) {
                ec_free(node->re_str);
@@ -98,7 +101,7 @@ int ec_node_re_set_regexp(struct ec_node *gen_node, const char *str)
 
 fail:
        ec_free(str_copy);
-       return ret;
+       return -1;
 }
 
 struct ec_node *ec_node_re(const char *id, const char *re_str)
index a74685f..a017635 100644 (file)
@@ -112,10 +112,8 @@ ec_node_re_lex_parse(const struct ec_node *gen_node,
                str = ec_strvec_val(strvec, 0);
                new_vec = tokenize(node->table, node->len, str);
        }
-       if (new_vec == NULL) {
-               ret = -ENOMEM;
+       if (new_vec == NULL)
                goto fail;
-       }
 
        ret = ec_node_parse_child(node->child, state, new_vec);
        if (ret < 0)
@@ -137,7 +135,7 @@ ec_node_re_lex_parse(const struct ec_node *gen_node,
 
  fail:
        ec_strvec_free(new_vec);
-       return ret;
+       return -1;
 }
 
 static void ec_node_re_lex_free_priv(struct ec_node *gen_node)
@@ -171,12 +169,10 @@ int ec_node_re_lex_add(struct ec_node *gen_node, const char *pattern, int keep)
        int ret;
        char *pat_dup = NULL;
 
-       ret = -ENOMEM;
        pat_dup = ec_strdup(pattern);
        if (pat_dup == NULL)
                goto fail;
 
-       ret = -ENOMEM;
        table = ec_realloc(node->table, sizeof(*table) * (node->len + 1));
        if (table == NULL)
                goto fail;
@@ -187,9 +183,9 @@ int ec_node_re_lex_add(struct ec_node *gen_node, const char *pattern, int keep)
                        "Regular expression <%s> compilation failed: %d\n",
                        pattern, ret);
                if (ret == REG_ESPACE)
-                       ret = -ENOMEM;
+                       errno = ENOMEM;
                else
-                       ret = -EINVAL;
+                       errno = EINVAL;
 
                goto fail;
        }
@@ -203,7 +199,7 @@ int ec_node_re_lex_add(struct ec_node *gen_node, const char *pattern, int keep)
 
 fail:
        ec_free(pat_dup);
-       return ret;
+       return -1;
 }
 
 struct ec_node *ec_node_re_lex(const char *id, struct ec_node *child)
index 164063e..77738ed 100644 (file)
@@ -45,10 +45,8 @@ ec_node_seq_parse(const struct ec_node *gen_node,
        for (i = 0; i < node->len; i++) {
                childvec = ec_strvec_ndup(strvec, len,
                        ec_strvec_len(strvec) - len);
-               if (childvec == NULL) {
-                       ret = -ENOMEM;
+               if (childvec == NULL)
                        goto fail;
-               }
 
                ret = ec_node_parse_child(node->table[i], state, childvec);
                if (ret < 0)
@@ -69,7 +67,7 @@ ec_node_seq_parse(const struct ec_node *gen_node,
 
 fail:
        ec_strvec_free(childvec);
-       return ret;
+       return -1;
 }
 
 static int
index c3a79ab..53122c4 100644 (file)
@@ -93,7 +93,7 @@ static char *unquote_str(const char *str, size_t n, int allow_missing_quote,
                        *missing_quote = str[0];
                if (allow_missing_quote == 0) {
                        ec_free(dst);
-                       errno = EINVAL;
+                       errno = EBADMSG;
                        return NULL;
                }
        }
@@ -229,13 +229,10 @@ ec_node_sh_lex_parse(const struct ec_node *gen_node,
                str = ec_strvec_val(strvec, 0);
                new_vec = tokenize(str, 0, 0, NULL);
        }
-       if (new_vec == NULL) {
-               if (errno == EINVAL)
-                       ret = EC_PARSE_NOMATCH;
-               else
-                       ret = -ENOMEM;
+       if (new_vec == NULL && errno == EBADMSG) /* quotes not closed */
+               return EC_PARSE_NOMATCH;
+       if (new_vec == NULL)
                goto fail;
-       }
 
        ret = ec_node_parse_child(node->child, state, new_vec);
        if (ret < 0)
@@ -257,7 +254,7 @@ ec_node_sh_lex_parse(const struct ec_node *gen_node,
 
  fail:
        ec_strvec_free(new_vec);
-       return ret;
+       return -1;
 }
 
 static int
index 6b11ebc..6f373e6 100644 (file)
@@ -101,19 +101,24 @@ EC_NODE_TYPE_REGISTER(ec_node_str_type);
 int ec_node_str_set_str(struct ec_node *gen_node, const char *str)
 {
        struct ec_node_str *node = (struct ec_node_str *)gen_node;
+       char *s = NULL;
        int ret;
 
        ret = ec_node_check_type(gen_node, &ec_node_str_type);
        if (ret < 0)
                return ret;
 
-       if (str == NULL)
-               return -EINVAL;
-       ec_free(node->string);
-       node->string = ec_strdup(str);
-       if (node->string == NULL)
-               return -ENOMEM;
+       if (str == NULL) {
+               errno = EINVAL;
+               return -1;
+       }
 
+       s = ec_strdup(str);
+       if (s == NULL)
+               return -1;
+
+       ec_free(node->string);
+       node->string = s;
        node->len = strlen(node->string);
 
        return 0;
index 62a2871..cc3442b 100644 (file)
@@ -54,10 +54,8 @@ __ec_node_subset_parse(struct parse_result *out, struct ec_node **table,
        memset(&best_result, 0, sizeof(best_result));
 
        child_table = ec_calloc(table_len - 1, sizeof(*child_table));
-       if (child_table == NULL) {
-               ret = -ENOMEM;
+       if (child_table == NULL)
                goto fail;
-       }
 
        for (i = 0; i < table_len; i++) {
                /* try to parse elt i */
@@ -80,10 +78,8 @@ __ec_node_subset_parse(struct parse_result *out, struct ec_node **table,
                len = ret;
                childvec = ec_strvec_ndup(strvec, len,
                                        ec_strvec_len(strvec) - len);
-               if (childvec == NULL) {
-                       ret = -ENOMEM;
+               if (childvec == NULL)
                        goto fail;
-               }
 
                memset(&result, 0, sizeof(result));
                ret = __ec_node_subset_parse(&result, child_table,
@@ -122,7 +118,7 @@ __ec_node_subset_parse(struct parse_result *out, struct ec_node **table,
        ec_parse_free(best_parse);
        ec_strvec_free(childvec);
        ec_free(child_table);
-       return ret;
+       return -1;
 }
 
 static int
index a6def04..6396fc1 100644 (file)
@@ -42,38 +42,46 @@ static int __ec_node_parse_child(const struct ec_node *node,
        struct ec_parse *child = NULL;
        int ret;
 
-       if (ec_node_type(node)->parse == NULL)
-               return -ENOTSUP;
+       if (ec_node_type(node)->parse == NULL) {
+               errno = ENOTSUP;
+               return -1;
+       }
 
        if (!is_root) {
                child = ec_parse(node);
                if (child == NULL)
-                       return -ENOMEM;
+                       return -1;
 
                ec_parse_link_child(state, child);
        } else {
                child = state;
        }
        ret = ec_node_type(node)->parse(node, child, strvec);
-       if (ret < 0 || ret == EC_PARSE_NOMATCH)
-               goto free;
+       if (ret < 0)
+               goto fail;
 
-       match_strvec = ec_strvec_ndup(strvec, 0, ret);
-       if (match_strvec == NULL) {
-               ret = -ENOMEM;
-               goto free;
+       if (ret == EC_PARSE_NOMATCH) {
+               if (!is_root) {
+                       ec_parse_unlink_child(state, child);
+                       ec_parse_free(child);
+               }
+               return ret;
        }
 
+       match_strvec = ec_strvec_ndup(strvec, 0, ret);
+       if (match_strvec == NULL)
+               goto fail;
+
        child->strvec = match_strvec;
 
        return ret;
 
-free:
+fail:
        if (!is_root) {
                ec_parse_unlink_child(state, child);
                ec_parse_free(child);
        }
-       return ret;
+       return -1;
 }
 
 int ec_node_parse_child(const struct ec_node *node, struct ec_parse *state,
@@ -244,7 +252,7 @@ static void __ec_parse_dump(FILE *out,
 {
        struct ec_parse *child;
        const struct ec_strvec *vec;
-       const char *id, *typename = "none";
+       const char *id = "none", *typename = "none";
 
        /* node can be null when parsing is incomplete */
        if (parse->node != NULL) {
index 0559214..79e644f 100644 (file)
@@ -92,9 +92,9 @@ struct ec_parse *ec_node_parse_strvec(const struct ec_node *node,
  *   possible descendants.
  *
  * return:
+ * the number of matched strings in strvec on success
  * EC_PARSE_NOMATCH (positive) if it does not match
- * any other negative value (-errno) for other errors
- * the number of matched strings in strvec
+ * -1 on error, and errno is set
  */
 int ec_node_parse_child(const struct ec_node *node,
                        struct ec_parse *state,
index bd23d98..132183d 100644 (file)
@@ -42,18 +42,18 @@ int ec_strvec_add(struct ec_strvec *strvec, const char *s)
        new_vec = ec_realloc(strvec->vec,
                sizeof(*strvec->vec) * (strvec->len + 1));
        if (new_vec == NULL)
-               return -ENOMEM;
+               return -1;
 
        strvec->vec = new_vec;
 
        elt = ec_malloc(sizeof(*elt));
        if (elt == NULL)
-               return -ENOMEM;
+               return -1;
 
        elt->str = ec_strdup(s);
        if (elt->str == NULL) {
                ec_free(elt);
-               return -ENOMEM;
+               return -1;
        }
        elt->refcnt = 1;
 
@@ -69,6 +69,9 @@ struct ec_strvec *ec_strvec_from_array(const char * const *strarr,
        size_t i;
 
        strvec = ec_strvec();
+       if (strvec == NULL)
+               goto fail;
+
        for (i = 0; i < n; i++) {
                if (ec_strvec_add(strvec, strarr[i]) < 0)
                        goto fail;
@@ -342,6 +345,16 @@ static int ec_strvec_testcase(void)
        free(buf);
        buf = NULL;
 
+       ec_strvec_del_last(strvec);
+       strvec2 = EC_STRVEC("0");
+       if (strvec2 == NULL) {
+               EC_TEST_ERR("cannot create strvec from array\n");
+               goto fail;
+       }
+       testres |= EC_TEST_CHECK(ec_strvec_cmp(strvec, strvec2) == 0,
+               "strvec and strvec2 should be equal\n");
+       ec_strvec_free(strvec2);
+
        f = open_memstream(&buf, &buflen);
        if (f == NULL)
                goto fail;
index 1e07c48..fe8c572 100644 (file)
@@ -9,6 +9,7 @@
 #include <errno.h>
 #include <assert.h>
 
+#include <ecoli_assert.h>
 #include <ecoli_malloc.h>
 #include <ecoli_log.h>
 #include <ecoli_test.h>
@@ -69,11 +70,11 @@ int ec_vec_add_by_ref(struct ec_vec *vec, void *ptr)
        if (vec->len + 1 > vec->size) {
                new_vec = ec_realloc(vec->vec, vec->elt_size * (vec->len + 1));
                if (new_vec == NULL)
-                       return -ENOMEM;
+                       return -1;
                vec->size = vec->len + 1;
+               vec->vec = new_vec;
        }
 
-       vec->vec = new_vec;
        memcpy(get_obj(vec, vec->len), ptr, vec->elt_size);
        vec->len++;
 
@@ -82,40 +83,35 @@ int ec_vec_add_by_ref(struct ec_vec *vec, void *ptr)
 
 int ec_vec_add_ptr(struct ec_vec *vec, void *elt)
 {
-       if (vec->elt_size != sizeof(elt))
-               return -EINVAL;
+       EC_CHECK_ARG(vec->elt_size == sizeof(elt), -1, EINVAL);
 
        return ec_vec_add_by_ref(vec, &elt);
 }
 
 int ec_vec_add_u8(struct ec_vec *vec, uint8_t elt)
 {
-       if (vec->elt_size != sizeof(elt))
-               return -EINVAL;
+       EC_CHECK_ARG(vec->elt_size == sizeof(elt), -1, EINVAL);
 
        return ec_vec_add_by_ref(vec, &elt);
 }
 
 int ec_vec_add_u16(struct ec_vec *vec, uint16_t elt)
 {
-       if (vec->elt_size != sizeof(elt))
-               return -EINVAL;
+       EC_CHECK_ARG(vec->elt_size == sizeof(elt), -1, EINVAL);
 
        return ec_vec_add_by_ref(vec, &elt);
 }
 
 int ec_vec_add_u32(struct ec_vec *vec, uint32_t elt)
 {
-       if (vec->elt_size != sizeof(elt))
-               return -EINVAL;
+       EC_CHECK_ARG(vec->elt_size == sizeof(elt), -1, EINVAL);
 
        return ec_vec_add_by_ref(vec, &elt);
 }
 
 int ec_vec_add_u64(struct ec_vec *vec, uint64_t elt)
 {
-       if (vec->elt_size != sizeof(elt))
-               return -EINVAL;
+       EC_CHECK_ARG(vec->elt_size == sizeof(elt), -1, EINVAL);
 
        return ec_vec_add_by_ref(vec, &elt);
 }
index 91a1e6e..47a26fb 100644 (file)
@@ -136,10 +136,10 @@ static char *get_node_help(const struct ec_comp_item *item)
 
 static int show_help(int ignore, int invoking_key)
 {
-       struct ec_comp_iter *iter;
+       struct ec_comp_iter *iter = NULL;
        const struct ec_comp_group *grp, *prev_grp = NULL;
        const struct ec_comp_item *item;
-       struct ec_comp *c;
+       struct ec_comp *c = NULL;
        struct ec_parse *p;
        char *line = NULL;
        unsigned int count;
index ccc5824..4517a79 100644 (file)
@@ -40,6 +40,8 @@ X save node path in completion to fix help string
 - anything better than weakref?
 - add ec_node_defaults.[ch] providing usual implementations of node methods
 X use vec for strvec
+- ELOOP in case of loop
+- remove weakref?
 
 dependencies
 ============