From 886aed6cb57bdcd88747c081229315acf1257473 Mon Sep 17 00:00:00 2001 From: Olivier Matz Date: Thu, 21 Jun 2018 22:46:07 +0200 Subject: [PATCH] config for int --- lib/ecoli_node_int.c | 278 +++++++++++++++++++++++++------------------ lib/ecoli_node_int.h | 9 -- 2 files changed, 164 insertions(+), 123 deletions(-) diff --git a/lib/ecoli_node_int.c b/lib/ecoli_node_int.c index c72ee04..daece01 100644 --- a/lib/ecoli_node_int.c +++ b/lib/ecoli_node_int.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -137,170 +138,225 @@ ec_node_uint_init_priv(struct ec_node *gen_node) return 0; } -static struct ec_node_type ec_node_int_type = { - .name = "int", - .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, +static const struct ec_config_schema ec_node_int_schema[] = { + { + .key = "min", + .desc = "The minimum valid value (included).", + .type = EC_CONFIG_TYPE_INT64, + }, + { + .key = "max", + .desc = "The maximum valid value (included).", + .type = EC_CONFIG_TYPE_INT64, + }, + { + .key = "base", + .desc = "The base to use. If unset or 0, try to guess.", + .type = EC_CONFIG_TYPE_UINT64, + }, }; -EC_NODE_TYPE_REGISTER(ec_node_int_type); - -struct ec_node *ec_node_int(const char *id, int64_t min, - int64_t max, unsigned int base) +static int ec_node_int_set_config(struct ec_node *gen_node, + const struct ec_config *config) { - struct ec_node *gen_node = NULL; + struct ec_node_int_uint *node = (struct ec_node_int_uint *)gen_node; + const struct ec_config *min_value = NULL; + const struct ec_config *max_value = NULL; + const struct ec_config *base_value = NULL; + char *s = NULL; - gen_node = __ec_node(&ec_node_int_type, id); - if (gen_node == NULL) - return NULL; + min_value = ec_config_dict_get(config, "min"); + max_value = ec_config_dict_get(config, "max"); + base_value = ec_config_dict_get(config, "base"); - if (ec_node_int_set_limits(gen_node, min, max) < 0) - goto fail; - if (ec_node_int_set_base(gen_node, base) < 0) + if (min_value && max_value && min_value->i64 > max_value->i64) { + errno = EINVAL; goto fail; + } - return gen_node; + if (min_value != NULL) { + node->check_min = true; + node->min = min_value->i64; + } else { + node->check_min = false; + } + if (max_value != NULL) { + node->check_max = true; + node->max = max_value->i64; + } else { + node->check_min = false; + } + if (base_value != NULL) + node->base = base_value->u64; + else + node->base = 0; + + return 0; fail: - ec_node_free(gen_node); - return NULL; + ec_free(s); + return -1; } -static struct ec_node_type ec_node_uint_type = { - .name = "uint", +static struct ec_node_type ec_node_int_type = { + .name = "int", + .schema = ec_node_int_schema, + .schema_len = EC_COUNT_OF(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, }; -EC_NODE_TYPE_REGISTER(ec_node_uint_type); +EC_NODE_TYPE_REGISTER(ec_node_int_type); -struct ec_node *ec_node_uint(const char *id, uint64_t min, - uint64_t max, unsigned int base) +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; + int ret; - gen_node = __ec_node(&ec_node_uint_type, id); + gen_node = __ec_node(&ec_node_int_type, id); if (gen_node == NULL) return NULL; - if (ec_node_uint_set_limits(gen_node, min, max) < 0) + config = ec_config_dict(); + if (config == NULL) goto fail; - if (ec_node_uint_set_base(gen_node, base) < 0) + + ret = ec_config_dict_set(config, "min", ec_config_i64(min)); + if (ret < 0) + goto fail; + ret = ec_config_dict_set(config, "max", ec_config_i64(max)); + if (ret < 0) + goto fail; + ret = ec_config_dict_set(config, "base", ec_config_u64(base)); + if (ret < 0) + goto fail; + + ret = ec_node_set_config(gen_node, config); + config = NULL; + if (ret < 0) goto fail; return gen_node; fail: + ec_config_free(config); ec_node_free(gen_node); return NULL; } -int ec_node_int_disable_limits(struct ec_node *gen_node) -{ - struct ec_node_int_uint *node = (struct ec_node_int_uint *)gen_node; - int ret; - - ret = ec_node_check_type(gen_node, &ec_node_int_type); - if (ret < 0) - return ret; - - node->check_min = false; - node->check_max = false; - - return 0; -} +static const struct ec_config_schema ec_node_uint_schema[] = { + { + .key = "min", + .desc = "The minimum valid value (included).", + .type = EC_CONFIG_TYPE_UINT64, + }, + { + .key = "max", + .desc = "The maximum valid value (included).", + .type = EC_CONFIG_TYPE_UINT64, + }, + { + .key = "base", + .desc = "The base to use. If unset or 0, try to guess.", + .type = EC_CONFIG_TYPE_UINT64, + }, +}; -int ec_node_int_set_limits(struct ec_node *gen_node, int64_t min, - int64_t max) +static int ec_node_uint_set_config(struct ec_node *gen_node, + const struct ec_config *config) { struct ec_node_int_uint *node = (struct ec_node_int_uint *)gen_node; - int ret; + const struct ec_config *min_value = NULL; + const struct ec_config *max_value = NULL; + const struct ec_config *base_value = NULL; + char *s = NULL; - ret = ec_node_check_type(gen_node, &ec_node_int_type); - if (ret < 0) - return ret; + min_value = ec_config_dict_get(config, "min"); + max_value = ec_config_dict_get(config, "max"); + base_value = ec_config_dict_get(config, "base"); - if (min > max) { + if (min_value && max_value && min_value->u64 > max_value->u64) { errno = EINVAL; - return -1; + goto fail; } - node->check_min = true; - node->min = min; - node->check_max = true; - node->max = max; - - return 0; -} - -int ec_node_int_set_base(struct ec_node *gen_node, unsigned int base) -{ - struct ec_node_int_uint *node = (struct ec_node_int_uint *)gen_node; - int ret; - - ret = ec_node_check_type(gen_node, &ec_node_int_type); - if (ret < 0) - return ret; - - node->base = base; + if (min_value != NULL) { + node->check_min = true; + node->min = min_value->u64; + } else { + node->check_min = false; + } + if (max_value != NULL) { + node->check_max = true; + node->max = max_value->u64; + } else { + node->check_min = false; + } + if (base_value != NULL) + node->base = base_value->u64; + else + node->base = 0; return 0; +fail: + ec_free(s); + return -1; } -int ec_node_uint_disable_limits(struct ec_node *gen_node) -{ - struct ec_node_int_uint *node = (struct ec_node_int_uint *)gen_node; - int ret; - - ret = ec_node_check_type(gen_node, &ec_node_uint_type); - if (ret < 0) - return ret; - - node->check_min = false; - node->check_max = false; +static struct ec_node_type ec_node_uint_type = { + .name = "uint", + .schema = ec_node_uint_schema, + .schema_len = EC_COUNT_OF(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), +}; - return 0; -} +EC_NODE_TYPE_REGISTER(ec_node_uint_type); -int ec_node_uint_set_limits(struct ec_node *gen_node, uint64_t min, - uint64_t max) +struct ec_node *ec_node_uint(const char *id, uint64_t min, + uint64_t max, unsigned int base) { - struct ec_node_int_uint *node = (struct ec_node_int_uint *)gen_node; + struct ec_config *config = NULL; + struct ec_node *gen_node = NULL; int ret; - ret = ec_node_check_type(gen_node, &ec_node_uint_type); - if (ret < 0) - return ret; - - if (min > max) { - errno = EINVAL; - return -1; - } - - node->check_min = true; - node->min = min; - node->check_max = true; - node->max = max; + gen_node = __ec_node(&ec_node_uint_type, id); + if (gen_node == NULL) + return NULL; - return 0; -} + config = ec_config_dict(); + if (config == NULL) + goto fail; -int ec_node_uint_set_base(struct ec_node *gen_node, unsigned int base) -{ - struct ec_node_int_uint *node = (struct ec_node_int_uint *)gen_node; - int ret; + ret = ec_config_dict_set(config, "min", ec_config_u64(min)); + if (ret < 0) + goto fail; + ret = ec_config_dict_set(config, "max", ec_config_u64(max)); + if (ret < 0) + goto fail; + ret = ec_config_dict_set(config, "base", ec_config_u64(base)); + if (ret < 0) + goto fail; - ret = ec_node_check_type(gen_node, &ec_node_uint_type); + ret = ec_node_set_config(gen_node, config); + config = NULL; if (ret < 0) - return ret; + goto fail; - node->base = base; + return gen_node; - return 0; +fail: + ec_config_free(config); + ec_node_free(gen_node); + return NULL; } int ec_node_int_getval(const struct ec_node *gen_node, const char *str, @@ -341,7 +397,7 @@ static int ec_node_int_testcase(void) struct ec_parse *p; struct ec_node *node; const char *s; - int testres = 0, ret; + int testres = 0; uint64_t u64; int64_t i64; @@ -361,9 +417,6 @@ static int ec_node_int_testcase(void) testres |= EC_TEST_CHECK_PARSE(node, -1, "zzz"); testres |= EC_TEST_CHECK_PARSE(node, -1, "0x100000000000000000"); testres |= EC_TEST_CHECK_PARSE(node, -1, "4r"); - ret = ec_node_uint_disable_limits(node); - testres |= EC_TEST_CHECK(ret == 0, "cannot disable limits"); - testres |= EC_TEST_CHECK_PARSE(node, 1, "0"); p = ec_node_parse(node, "1"); s = ec_strvec_val(ec_parse_strvec(p), 0); @@ -393,9 +446,6 @@ static int ec_node_int_testcase(void) testres |= EC_TEST_CHECK_PARSE(node, -1, "-2"); testres |= EC_TEST_CHECK_PARSE(node, -1, "zzz"); testres |= EC_TEST_CHECK_PARSE(node, -1, "4r"); - ret = ec_node_int_disable_limits(node); - testres |= EC_TEST_CHECK(ret == 0, "cannot disable limits"); - testres |= EC_TEST_CHECK_PARSE(node, 1, "-2"); p = ec_node_parse(node, "10"); s = ec_strvec_val(ec_parse_strvec(p), 0); diff --git a/lib/ecoli_node_int.h b/lib/ecoli_node_int.h index 11acfd9..b64c60c 100644 --- a/lib/ecoli_node_int.h +++ b/lib/ecoli_node_int.h @@ -15,11 +15,6 @@ struct ec_node *ec_node_int(const char *id, int64_t min, int64_t max, unsigned int base); -int ec_node_int_disable_limits(struct ec_node *node); -int ec_node_int_set_limits(struct ec_node *node, int64_t min, - int64_t max); -int ec_node_int_set_base(struct ec_node *node, unsigned int base); - int ec_node_int_getval(const struct ec_node *node, const char *str, int64_t *result); @@ -27,10 +22,6 @@ int ec_node_int_getval(const struct ec_node *node, const char *str, struct ec_node *ec_node_uint(const char *id, uint64_t min, uint64_t max, unsigned int base); -int ec_node_uint_disable_limits(struct ec_node *node); -int ec_node_uint_set_limits(struct ec_node *node, uint64_t min, - uint64_t max); -int ec_node_uint_set_base(struct ec_node *node, unsigned int base); int ec_node_uint_getval(const struct ec_node *node, const char *str, uint64_t *result); -- 2.20.1