api doc and minor changes
[protos/libecoli.git] / src / ecoli_node_int.c
index 9b56e22..efebae9 100644 (file)
 #include <ecoli_config.h>
 #include <ecoli_parse.h>
 #include <ecoli_complete.h>
-#include <ecoli_node_int.h>
+#include <ecoli_string.h>
 #include <ecoli_test.h>
+#include <ecoli_node_int.h>
 
 EC_LOG_TYPE_REGISTER(node_int);
 
 /* common to int and uint */
 struct ec_node_int_uint {
-       struct ec_node gen;
        bool is_signed;
        bool check_min;
        bool check_max;
@@ -40,101 +40,71 @@ struct ec_node_int_uint {
        unsigned int base;
 };
 
-/* XXX to utils.c ? */
-static int parse_llint(struct ec_node_int_uint *node, const char *str,
+static int parse_llint(struct ec_node_int_uint *priv, const char *str,
        int64_t *val)
 {
-       char *endptr;
-       int save_errno = errno;
-
-       errno = 0;
-       *val = strtoll(str, &endptr, node->base);
-
-       if ((errno == ERANGE && (*val == LLONG_MAX || *val == LLONG_MIN)) ||
-                       (errno != 0 && *val == 0))
-               return -1;
-
-       if (node->check_min && *val < node->min) {
-               errno = ERANGE;
-               return -1;
-       }
+       int64_t min, max;
 
-       if (node->check_max && *val > node->max) {
-               errno = ERANGE;
-               return -1;
-       }
-
-       if (*endptr != 0) {
-               errno = EINVAL;
-               return -1;
-       }
+       if (priv->check_min)
+               min = priv->min;
+       else
+               min = LLONG_MIN;
+       if (priv->check_max)
+               max = priv->max;
+       else
+               max = LLONG_MAX;
 
-       errno = save_errno;
-       return 0;
+       return ec_str_parse_llint(str, priv->base, min, max, val);
 }
 
-static int parse_ullint(struct ec_node_int_uint *node, const char *str,
+static int parse_ullint(struct ec_node_int_uint *priv, const char *str,
                        uint64_t *val)
 {
-       char *endptr;
-       int save_errno = errno;
-
-       /* since a negative input is silently converted to a positive
-        * one by strtoull(), first check that it is positive */
-       if (strchr(str, '-'))
-               return -1;
-
-       errno = 0;
-       *val = strtoull(str, &endptr, node->base);
-
-       if ((errno == ERANGE && *val == ULLONG_MAX) ||
-                       (errno != 0 && *val == 0))
-               return -1;
-
-       if (node->check_min && *val < node->umin)
-               return -1;
+       uint64_t min, max;
 
-       if (node->check_max && *val > node->umax)
-               return -1;
-
-       if (*endptr != 0)
-               return -1;
+       if (priv->check_min)
+               min = priv->min;
+       else
+               min = 0;
+       if (priv->check_max)
+               max = priv->max;
+       else
+               max = ULLONG_MAX;
 
-       errno = save_errno;
-       return 0;
+       return ec_str_parse_ullint(str, priv->base, min, max, val);
 }
 
-static int ec_node_int_uint_parse(const struct ec_node *gen_node,
-                       struct ec_parse *state,
+static int ec_node_int_uint_parse(const struct ec_node *node,
+                       struct ec_pnode *pstate,
                        const struct ec_strvec *strvec)
 {
-       struct ec_node_int_uint *node = (struct ec_node_int_uint *)gen_node;
+       struct ec_node_int_uint *priv = ec_node_priv(node);
        const char *str;
        uint64_t u64;
        int64_t i64;
 
-       (void)state;
+       (void)pstate;
 
        if (ec_strvec_len(strvec) == 0)
                return EC_PARSE_NOMATCH;
 
        str = ec_strvec_val(strvec, 0);
-       if (node->is_signed) {
-               if (parse_llint(node, str, &i64) < 0)
+       if (priv->is_signed) {
+               if (parse_llint(priv, str, &i64) < 0)
                        return EC_PARSE_NOMATCH;
        } else {
-               if (parse_ullint(node, str, &u64) < 0)
+               if (parse_ullint(priv, str, &u64) < 0)
                        return EC_PARSE_NOMATCH;
        }
        return 1;
 }
 
 static int
-ec_node_uint_init_priv(struct ec_node *gen_node)
+ec_node_uint_init_priv(struct ec_node *node)
 {
-       struct ec_node_int_uint *node = (struct ec_node_int_uint *)gen_node;
+       struct ec_node_int_uint *priv = ec_node_priv(node);
 
-       node->is_signed = true;
+       priv->is_signed = true;
 
        return 0;
 }
@@ -160,10 +130,10 @@ static const struct ec_config_schema ec_node_int_schema[] = {
        },
 };
 
-static int ec_node_int_set_config(struct ec_node *gen_node,
+static int ec_node_int_set_config(struct ec_node *node,
                                const struct ec_config *config)
 {
-       struct ec_node_int_uint *node = (struct ec_node_int_uint *)gen_node;
+       struct ec_node_int_uint *priv = ec_node_priv(node);
        const struct ec_config *min_value = NULL;
        const struct ec_config *max_value = NULL;
        const struct ec_config *base_value = NULL;
@@ -179,21 +149,21 @@ static int ec_node_int_set_config(struct ec_node *gen_node,
        }
 
        if (min_value != NULL) {
-               node->check_min = true;
-               node->min = min_value->i64;
+               priv->check_min = true;
+               priv->min = min_value->i64;
        } else {
-               node->check_min = false;
+               priv->check_min = false;
        }
        if (max_value != NULL) {
-               node->check_max = true;
-               node->max = max_value->i64;
+               priv->check_max = true;
+               priv->max = max_value->i64;
        } else {
-               node->check_min = false;
+               priv->check_min = false;
        }
        if (base_value != NULL)
-               node->base = base_value->u64;
+               priv->base = base_value->u64;
        else
-               node->base = 0;
+               priv->base = 0;
 
        return 0;
 
@@ -207,7 +177,6 @@ static struct ec_node_type ec_node_int_type = {
        .schema = ec_node_int_schema,
        .set_config = ec_node_int_set_config,
        .parse = ec_node_int_uint_parse,
-       .complete = ec_node_complete_unknown,
        .size = sizeof(struct ec_node_int_uint),
        .init_priv = ec_node_uint_init_priv,
 };
@@ -218,11 +187,11 @@ struct ec_node *ec_node_int(const char *id, int64_t min,
        int64_t max, unsigned int base)
 {
        struct ec_config *config = NULL;
-       struct ec_node *gen_node = NULL;
+       struct ec_node *node = NULL;
        int ret;
 
-       gen_node = ec_node_from_type(&ec_node_int_type, id);
-       if (gen_node == NULL)
+       node = ec_node_from_type(&ec_node_int_type, id);
+       if (node == NULL)
                return NULL;
 
        config = ec_config_dict();
@@ -239,16 +208,16 @@ struct ec_node *ec_node_int(const char *id, int64_t min,
        if (ret < 0)
                goto fail;
 
-       ret = ec_node_set_config(gen_node, config);
+       ret = ec_node_set_config(node, config);
        config = NULL;
        if (ret < 0)
                goto fail;
 
-       return gen_node;
+       return node;
 
 fail:
        ec_config_free(config);
-       ec_node_free(gen_node);
+       ec_node_free(node);
        return NULL;
 }
 
@@ -273,10 +242,10 @@ static const struct ec_config_schema ec_node_uint_schema[] = {
        },
 };
 
-static int ec_node_uint_set_config(struct ec_node *gen_node,
+static int ec_node_uint_set_config(struct ec_node *node,
                                const struct ec_config *config)
 {
-       struct ec_node_int_uint *node = (struct ec_node_int_uint *)gen_node;
+       struct ec_node_int_uint *priv = ec_node_priv(node);
        const struct ec_config *min_value = NULL;
        const struct ec_config *max_value = NULL;
        const struct ec_config *base_value = NULL;
@@ -292,21 +261,21 @@ static int ec_node_uint_set_config(struct ec_node *gen_node,
        }
 
        if (min_value != NULL) {
-               node->check_min = true;
-               node->min = min_value->u64;
+               priv->check_min = true;
+               priv->min = min_value->u64;
        } else {
-               node->check_min = false;
+               priv->check_min = false;
        }
        if (max_value != NULL) {
-               node->check_max = true;
-               node->max = max_value->u64;
+               priv->check_max = true;
+               priv->max = max_value->u64;
        } else {
-               node->check_min = false;
+               priv->check_min = false;
        }
        if (base_value != NULL)
-               node->base = base_value->u64;
+               priv->base = base_value->u64;
        else
-               node->base = 0;
+               priv->base = 0;
 
        return 0;
 
@@ -320,7 +289,6 @@ static struct ec_node_type ec_node_uint_type = {
        .schema = ec_node_uint_schema,
        .set_config = ec_node_uint_set_config,
        .parse = ec_node_int_uint_parse,
-       .complete = ec_node_complete_unknown,
        .size = sizeof(struct ec_node_int_uint),
 };
 
@@ -330,11 +298,11 @@ struct ec_node *ec_node_uint(const char *id, uint64_t min,
        uint64_t max, unsigned int base)
 {
        struct ec_config *config = NULL;
-       struct ec_node *gen_node = NULL;
+       struct ec_node *node = NULL;
        int ret;
 
-       gen_node = ec_node_from_type(&ec_node_uint_type, id);
-       if (gen_node == NULL)
+       node = ec_node_from_type(&ec_node_uint_type, id);
+       if (node == NULL)
                return NULL;
 
        config = ec_config_dict();
@@ -351,46 +319,46 @@ struct ec_node *ec_node_uint(const char *id, uint64_t min,
        if (ret < 0)
                goto fail;
 
-       ret = ec_node_set_config(gen_node, config);
+       ret = ec_node_set_config(node, config);
        config = NULL;
        if (ret < 0)
                goto fail;
 
-       return gen_node;
+       return node;
 
 fail:
        ec_config_free(config);
-       ec_node_free(gen_node);
+       ec_node_free(node);
        return NULL;
 }
 
-int ec_node_int_getval(const struct ec_node *gen_node, const char *str,
+int ec_node_int_getval(const struct ec_node *node, const char *str,
                        int64_t *result)
 {
-       struct ec_node_int_uint *node = (struct ec_node_int_uint *)gen_node;
+       struct ec_node_int_uint *priv = ec_node_priv(node);
        int ret;
 
-       ret = ec_node_check_type(gen_node, &ec_node_int_type);
+       ret = ec_node_check_type(node, &ec_node_int_type);
        if (ret < 0)
                return ret;
 
-       if (parse_llint(node, str, result) < 0)
+       if (parse_llint(priv, str, result) < 0)
                return -1;
 
        return 0;
 }
 
-int ec_node_uint_getval(const struct ec_node *gen_node, const char *str,
+int ec_node_uint_getval(const struct ec_node *node, const char *str,
                        uint64_t *result)
 {
-       struct ec_node_int_uint *node = (struct ec_node_int_uint *)gen_node;
+       struct ec_node_int_uint *priv = ec_node_priv(node);
        int ret;
 
-       ret = ec_node_check_type(gen_node, &ec_node_uint_type);
+       ret = ec_node_check_type(node, &ec_node_uint_type);
        if (ret < 0)
                return ret;
 
-       if (parse_ullint(node, str, result) < 0)
+       if (parse_ullint(priv, str, result) < 0)
                return -1;
 
        return 0;
@@ -399,7 +367,7 @@ int ec_node_uint_getval(const struct ec_node *gen_node, const char *str,
 /* LCOV_EXCL_START */
 static int ec_node_int_testcase(void)
 {
-       struct ec_parse *p;
+       struct ec_pnode *p;
        struct ec_node *node;
        const char *s;
        int testres = 0;
@@ -423,19 +391,19 @@ static int ec_node_int_testcase(void)
        testres |= EC_TEST_CHECK_PARSE(node, -1, "0x100000000000000000");
        testres |= EC_TEST_CHECK_PARSE(node, -1, "4r");
 
-       p = ec_node_parse(node, "1");
-       s = ec_strvec_val(ec_parse_strvec(p), 0);
+       p = ec_parse(node, "1");
+       s = ec_strvec_val(ec_pnode_strvec(p), 0);
        testres |= EC_TEST_CHECK(s != NULL &&
                ec_node_uint_getval(node, s, &u64) == 0 &&
                u64 == 1, "bad integer value");
-       ec_parse_free(p);
+       ec_pnode_free(p);
 
-       p = ec_node_parse(node, "10");
-       s = ec_strvec_val(ec_parse_strvec(p), 0);
+       p = ec_parse(node, "10");
+       s = ec_strvec_val(ec_pnode_strvec(p), 0);
        testres |= EC_TEST_CHECK(s != NULL &&
                ec_node_uint_getval(node, s, &u64) == 0 &&
                u64 == 10, "bad integer value");
-       ec_parse_free(p);
+       ec_pnode_free(p);
        ec_node_free(node);
 
        node = ec_node_int(EC_NO_ID, -1, LLONG_MAX, 16);
@@ -452,12 +420,12 @@ static int ec_node_int_testcase(void)
        testres |= EC_TEST_CHECK_PARSE(node, -1, "zzz");
        testres |= EC_TEST_CHECK_PARSE(node, -1, "4r");
 
-       p = ec_node_parse(node, "10");
-       s = ec_strvec_val(ec_parse_strvec(p), 0);
+       p = ec_parse(node, "10");
+       s = ec_strvec_val(ec_pnode_strvec(p), 0);
        testres |= EC_TEST_CHECK(s != NULL &&
                ec_node_int_getval(node, s, &i64) == 0 &&
                i64 == 16, "bad integer value");
-       ec_parse_free(p);
+       ec_pnode_free(p);
        ec_node_free(node);
 
        node = ec_node_int(EC_NO_ID, LLONG_MIN, 0, 10);
@@ -479,14 +447,14 @@ static int ec_node_int_testcase(void)
                return -1;
        }
        testres |= EC_TEST_CHECK_COMPLETE(node,
-               "", EC_NODE_ENDLIST,
-               EC_NODE_ENDLIST);
+               "", EC_VA_END,
+               EC_VA_END);
        testres |= EC_TEST_CHECK_COMPLETE(node,
-               "x", EC_NODE_ENDLIST,
-               EC_NODE_ENDLIST);
+               "x", EC_VA_END,
+               EC_VA_END);
        testres |= EC_TEST_CHECK_COMPLETE(node,
-               "1", EC_NODE_ENDLIST,
-               EC_NODE_ENDLIST);
+               "1", EC_VA_END,
+               EC_VA_END);
        ec_node_free(node);
 
        return testres;