#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;
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;
}
},
};
-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;
}
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;
.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,
};
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();
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;
}
},
};
-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;
}
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;
.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),
};
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();
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;
/* 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;
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);
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);
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;