X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Fecoli_config.c;h=63b572555c28ca6cfd071f7e75bff1d97e328b3e;hb=d8c60a316b5c2a8b959f6191274504d433cf64f0;hp=9b07700ff00e228032706e05e04c8ee9cc31c864;hpb=633f0c3ee0d9966ffe2d6ec003692bef18e5c918;p=protos%2Flibecoli.git diff --git a/lib/ecoli_config.c b/lib/ecoli_config.c index 9b07700..63b5725 100644 --- a/lib/ecoli_config.c +++ b/lib/ecoli_config.c @@ -18,18 +18,31 @@ EC_LOG_TYPE_REGISTER(config); -#ifndef EC_COUNT_OF //XXX -#define EC_COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / \ - ((size_t)(!(sizeof(x) % sizeof(0[x]))))) -#endif +const char *ec_config_reserved_keys[] = { + "id", + "attrs", + "help", + "type", +}; static int __ec_config_dump(FILE *out, const char *key, const struct ec_config *config, size_t indent); static int ec_config_dict_validate(const struct ec_keyval *dict, - const struct ec_config_schema *schema, - size_t schema_len); + const struct ec_config_schema *schema); + +bool +ec_config_key_is_reserved(const char *name) +{ + size_t i; + + for (i = 0; i < EC_COUNT_OF(ec_config_reserved_keys); i++) { + if (!strcmp(name, ec_config_reserved_keys[i])) + return true; + } + return false; +} /* return ec_value type as a string */ static const char * @@ -47,9 +60,21 @@ ec_config_type_str(enum ec_config_type type) } } +static size_t +ec_config_schema_len(const struct ec_config_schema *schema) +{ + size_t i; + + if (schema == NULL) + return 0; + for (i = 0; schema[i].type != EC_CONFIG_TYPE_NONE; i++) + ; + return i; +} + static int __ec_config_schema_validate(const struct ec_config_schema *schema, - size_t schema_len, enum ec_config_type type) + enum ec_config_type type) { size_t i, j; int ret; @@ -61,10 +86,11 @@ __ec_config_schema_validate(const struct ec_config_schema *schema, return -1; } } else if (type == EC_CONFIG_TYPE_DICT) { - for (i = 0; i < schema_len; i++) { + for (i = 0; schema[i].type != EC_CONFIG_TYPE_NONE; i++) { if (schema[i].key == NULL) { errno = EINVAL; - EC_LOG(EC_LOG_ERR, "dict schema key should not be NULL\n"); + EC_LOG(EC_LOG_ERR, + "dict schema key should not be NULL\n"); return -1; } } @@ -74,9 +100,16 @@ __ec_config_schema_validate(const struct ec_config_schema *schema, return -1; } - for (i = 0; i < schema_len; i++) { + for (i = 0; schema[i].type != EC_CONFIG_TYPE_NONE; i++) { + if (schema[i].key != NULL && + ec_config_key_is_reserved(schema[i].key)) { + errno = EINVAL; + EC_LOG(EC_LOG_ERR, + "key name <%s> is reserved\n", schema[i].key); + return -1; + } /* check for duplicate name if more than one element */ - for (j = i + 1; j < schema_len; j++) { + for (j = i + 1; schema[j].type != EC_CONFIG_TYPE_NONE; j++) { if (!strcmp(schema[i].key, schema[j].key)) { errno = EEXIST; EC_LOG(EC_LOG_ERR, @@ -92,8 +125,8 @@ __ec_config_schema_validate(const struct ec_config_schema *schema, case EC_CONFIG_TYPE_UINT64: case EC_CONFIG_TYPE_STRING: case EC_CONFIG_TYPE_NODE: - if (schema[i].subschema != NULL || - schema[i].subschema_len != 0) { + if (schema[i].subschema != NULL || ec_config_schema_len( + schema[i].subschema) != 0) { errno = EINVAL; EC_LOG(EC_LOG_ERR, "key <%s> should not have subtype/subschema\n", @@ -102,8 +135,8 @@ __ec_config_schema_validate(const struct ec_config_schema *schema, } break; case EC_CONFIG_TYPE_LIST: - if (schema[i].subschema == NULL || - schema[i].subschema_len != 1) { + if (schema[i].subschema == NULL || ec_config_schema_len( + schema[i].subschema) != 1) { errno = EINVAL; EC_LOG(EC_LOG_ERR, "key <%s> must have subschema of length 1\n", @@ -112,8 +145,8 @@ __ec_config_schema_validate(const struct ec_config_schema *schema, } break; case EC_CONFIG_TYPE_DICT: - if (schema[i].subschema == NULL || - schema[i].subschema_len == 0) { + if (schema[i].subschema == NULL || ec_config_schema_len( + schema[i].subschema) == 0) { errno = EINVAL; EC_LOG(EC_LOG_ERR, "key <%s> must have subschema\n", @@ -132,7 +165,6 @@ __ec_config_schema_validate(const struct ec_config_schema *schema, continue; ret = __ec_config_schema_validate(schema[i].subschema, - schema[i].subschema_len, schema[i].type); if (ret < 0) { EC_LOG(EC_LOG_ERR, "cannot parse subschema %s%s\n", @@ -146,22 +178,21 @@ __ec_config_schema_validate(const struct ec_config_schema *schema, } int -ec_config_schema_validate(const struct ec_config_schema *schema, - size_t schema_len) +ec_config_schema_validate(const struct ec_config_schema *schema) { - return __ec_config_schema_validate(schema, schema_len, - EC_CONFIG_TYPE_DICT); + return __ec_config_schema_validate(schema, EC_CONFIG_TYPE_DICT); } static void __ec_config_schema_dump(FILE *out, const struct ec_config_schema *schema, - size_t schema_len, size_t indent) + size_t indent) { size_t i; - for (i = 0; i < schema_len; i++) { - fprintf(out, "%*s" "%s%s(%s): %s\n", + for (i = 0; schema[i].type != EC_CONFIG_TYPE_NONE; i++) { + fprintf(out, "%*s" "%s%s%stype=%s desc='%s'\n", (int)indent * 4, "", + schema[i].key ? "key=": "", schema[i].key ? : "", schema[i].key ? " ": "", ec_config_type_str(schema[i].type), @@ -169,22 +200,26 @@ __ec_config_schema_dump(FILE *out, const struct ec_config_schema *schema, if (schema[i].subschema == NULL) continue; __ec_config_schema_dump(out, schema[i].subschema, - schema[i].subschema_len, indent + 1); + indent + 1); } } void -ec_config_schema_dump(FILE *out, const struct ec_config_schema *schema, - size_t schema_len) +ec_config_schema_dump(FILE *out, const struct ec_config_schema *schema) { fprintf(out, "------------------- schema dump:\n"); - if (schema == NULL || schema_len == 0) { + if (schema == NULL) { fprintf(out, "no schema\n"); return; } - __ec_config_schema_dump(out, schema, schema_len, 0); + __ec_config_schema_dump(out, schema, 0); +} + +enum ec_config_type ec_config_get_type(const struct ec_config *config) +{ + return config->type; } struct ec_config * @@ -325,38 +360,14 @@ ec_config_list(void) return value; } -int -ec_config_set_schema(struct ec_config *dict, - const struct ec_config_schema *schema, - size_t schema_len) -{ - if (dict->type != EC_CONFIG_TYPE_DICT) { - errno = EINVAL; - goto fail; - } - - if (ec_config_schema_validate(schema, schema_len) < 0) - goto fail; - - dict->schema = schema; - dict->schema_len = schema_len; - - return 0; - -fail: - return -1; -} - const struct ec_config_schema * ec_config_schema_lookup(const struct ec_config_schema *schema, - size_t schema_len, const char *key, - enum ec_config_type type) + const char *key) { size_t i; - for (i = 0; i < schema_len; i++) { - if (!strcmp(key, schema[i].key) && - type == schema[i].type) + for (i = 0; schema[i].type != EC_CONFIG_TYPE_NONE; i++) { + if (!strcmp(key, schema[i].key)) return &schema[i]; } @@ -448,6 +459,11 @@ int ec_config_cmp(const struct ec_config *value1, const struct ec_config *value2) { + if (value1 == NULL || value2 == NULL) { + errno = EINVAL; + return -1; + } + if (value1->type != value2->type) return -1; @@ -496,7 +512,7 @@ ec_config_list_validate(const struct ec_config_list *list, return -1; } else if (value->type == EC_CONFIG_TYPE_DICT) { if (ec_config_dict_validate(value->dict, - sch->subschema, sch->subschema_len) < 0) + sch->subschema) < 0) return -1; } } @@ -506,8 +522,7 @@ ec_config_list_validate(const struct ec_config_list *list, static int ec_config_dict_validate(const struct ec_keyval *dict, - const struct ec_config_schema *schema, - size_t schema_len) + const struct ec_config_schema *schema) { const struct ec_config *value; struct ec_keyval_iter *iter = NULL; @@ -520,20 +535,18 @@ ec_config_dict_validate(const struct ec_keyval *dict, key = ec_keyval_iter_get_key(iter); value = ec_keyval_iter_get_val(iter); - sch = ec_config_schema_lookup(schema, schema_len, - key, value->type); - if (sch == NULL) { + sch = ec_config_schema_lookup(schema, key); + if (sch == NULL || sch->type != value->type) { errno = EBADMSG; goto fail; } - if (value->type == EC_CONFIG_TYPE_LIST) { if (ec_config_list_validate(&value->list, sch->subschema) < 0) goto fail; } else if (value->type == EC_CONFIG_TYPE_DICT) { if (ec_config_dict_validate(value->dict, - sch->subschema, sch->subschema_len) < 0) + sch->subschema) < 0) goto fail; } } @@ -547,19 +560,15 @@ fail: } int -ec_config_validate(const struct ec_config *dict) +ec_config_validate(const struct ec_config *dict, + const struct ec_config_schema *schema) { - if (dict->type != EC_CONFIG_TYPE_DICT) { + if (dict->type != EC_CONFIG_TYPE_DICT || schema == NULL) { errno = EINVAL; goto fail; } - if (dict->schema == NULL || dict->schema_len == 0) { - errno = ENOENT; - goto fail; - } - if (ec_config_dict_validate(dict->dict, dict->schema, - dict->schema_len) < 0) + if (ec_config_dict_validate(dict->dict, schema) < 0) goto fail; return 0 @@ -568,18 +577,42 @@ fail: return -1; } - -const struct ec_config * -ec_config_get(const struct ec_config *config, const char *key) +struct ec_config * +ec_config_dict_get(const struct ec_config *config, const char *key) { - if (config == NULL) + if (config == NULL) { + errno = EINVAL; return NULL; + } + + if (config->type != EC_CONFIG_TYPE_DICT) { + errno = EINVAL; + return NULL; + } return ec_keyval_get(config->dict, key); } +struct ec_config * +ec_config_list_first(struct ec_config *list) +{ + if (list == NULL || list->type != EC_CONFIG_TYPE_LIST) { + errno = EINVAL; + return NULL; + } + + return TAILQ_FIRST(&list->list); +} + +struct ec_config * +ec_config_list_next(struct ec_config *list, struct ec_config *config) +{ + (void)list; + return TAILQ_NEXT(config, next); +} + /* value is consumed */ -int ec_config_set(struct ec_config *config, const char *key, +int ec_config_dict_set(struct ec_config *config, const char *key, struct ec_config *value) { void (*free_cb)(struct ec_config *) = ec_config_free; @@ -601,12 +634,26 @@ fail: return -1; } +int ec_config_dict_del(struct ec_config *config, const char *key) +{ + if (config == NULL || key == NULL) { + errno = EINVAL; + return -1; + } + if (config->type != EC_CONFIG_TYPE_DICT) { + errno = EINVAL; + return -1; + } + + return ec_keyval_del(config->dict, key); +} + /* value is consumed */ int -ec_config_add(struct ec_config *list, +ec_config_list_add(struct ec_config *list, struct ec_config *value) { - if (list->type != EC_CONFIG_TYPE_LIST) { + if (list == NULL || list->type != EC_CONFIG_TYPE_LIST || value == NULL) { errno = EINVAL; goto fail; } @@ -620,6 +667,103 @@ fail: return -1; } +int ec_config_list_del(struct ec_config *list, struct ec_config *config) +{ + if (list == NULL || list->type != EC_CONFIG_TYPE_LIST) { + errno = EINVAL; + return -1; + } + + TAILQ_REMOVE(&list->list, config, next); + ec_config_free(config); + return 0; +} + +static struct ec_config * +ec_config_list_dup(const struct ec_config_list *list) +{ + struct ec_config *dup = NULL, *v, *value; + + dup = ec_config_list(); + if (dup == NULL) + goto fail; + + TAILQ_FOREACH(v, list, next) { + value = ec_config_dup(v); + if (value == NULL) + goto fail; + if (ec_config_list_add(dup, value) < 0) + goto fail; + } + + return dup; + +fail: + ec_config_free(dup); + return NULL; +} + +static struct ec_config * +ec_config_dict_dup(const struct ec_keyval *dict) +{ + struct ec_config *dup = NULL, *value; + struct ec_keyval_iter *iter = NULL; + const char *key; + + dup = ec_config_dict(); + if (dup == NULL) + goto fail; + + for (iter = ec_keyval_iter(dict); + ec_keyval_iter_valid(iter); + ec_keyval_iter_next(iter)) { + key = ec_keyval_iter_get_key(iter); + value = ec_config_dup(ec_keyval_iter_get_val(iter)); + if (value == NULL) + goto fail; + if (ec_config_dict_set(dup, key, value) < 0) + goto fail; + } + ec_keyval_iter_free(iter); + + return dup; + +fail: + ec_config_free(dup); + ec_keyval_iter_free(iter); + return NULL; +} + +struct ec_config * +ec_config_dup(const struct ec_config *config) +{ + if (config == NULL) { + errno = EINVAL; + return NULL; + } + + switch (config->type) { + case EC_CONFIG_TYPE_BOOL: + return ec_config_bool(config->boolean); + case EC_CONFIG_TYPE_INT64: + return ec_config_i64(config->i64); + case EC_CONFIG_TYPE_UINT64: + return ec_config_u64(config->u64); + case EC_CONFIG_TYPE_STRING: + return ec_config_string(config->string); + case EC_CONFIG_TYPE_NODE: + return ec_config_node(ec_node_clone(config->node)); + case EC_CONFIG_TYPE_LIST: + return ec_config_list_dup(&config->list); + case EC_CONFIG_TYPE_DICT: + return ec_config_dict_dup(config->dict); + default: + errno = EINVAL; + break; + } + + return NULL; +} static int ec_config_list_dump(FILE *out, const struct ec_config_list *list, @@ -729,69 +873,78 @@ ec_config_dump(FILE *out, const struct ec_config *config) } /* LCOV_EXCL_START */ -static const struct ec_config_schema intlist_elt[] = { +static const struct ec_config_schema sch_intlist_elt[] = { { .desc = "This is a description for int", .type = EC_CONFIG_TYPE_INT64, }, + { + .type = EC_CONFIG_TYPE_NONE, + }, }; -static const struct ec_config_schema dict[] = { +static const struct ec_config_schema sch_dict[] = { { - .key = "int", + .key = "my_int", .desc = "This is a description for int", .type = EC_CONFIG_TYPE_INT64, }, { - .key = "int2", + .key = "my_int2", .desc = "This is a description for int2", .type = EC_CONFIG_TYPE_INT64, }, + { + .type = EC_CONFIG_TYPE_NONE, + }, }; -static const struct ec_config_schema dictlist_elt[] = { +static const struct ec_config_schema sch_dictlist_elt[] = { { .desc = "This is a description for dict", .type = EC_CONFIG_TYPE_DICT, - .subschema = dict, - .subschema_len = EC_COUNT_OF(dict), + .subschema = sch_dict, + }, + { + .type = EC_CONFIG_TYPE_NONE, }, }; -static const struct ec_config_schema baseconfig[] = { +static const struct ec_config_schema sch_baseconfig[] = { { - .key = "bool", + .key = "my_bool", .desc = "This is a description for bool", .type = EC_CONFIG_TYPE_BOOL, }, { - .key = "int", + .key = "my_int", .desc = "This is a description for int", .type = EC_CONFIG_TYPE_INT64, }, { - .key = "string", + .key = "my_string", .desc = "This is a description for string", .type = EC_CONFIG_TYPE_STRING, }, { - .key = "node", + .key = "my_node", .desc = "This is a description for node", .type = EC_CONFIG_TYPE_NODE, }, { - .key = "intlist", + .key = "my_intlist", .desc = "This is a description for list", .type = EC_CONFIG_TYPE_LIST, - .subschema = intlist_elt, - .subschema_len = EC_COUNT_OF(intlist_elt), + .subschema = sch_intlist_elt, }, { - .key = "dictlist", + .key = "my_dictlist", .desc = "This is a description for list", .type = EC_CONFIG_TYPE_LIST, - .subschema = dictlist_elt, - .subschema_len = EC_COUNT_OF(dictlist_elt), + .subschema = sch_dictlist_elt, + }, + { + .type = EC_CONFIG_TYPE_NONE, }, }; @@ -800,42 +953,44 @@ static int ec_config_testcase(void) struct ec_node *node = NULL; struct ec_keyval *dict = NULL; const struct ec_config *value = NULL; - struct ec_config *config = NULL, *list = NULL, *subconfig = NULL; - //const struct ec_config *pvalue; + struct ec_config *config = NULL, *config2 = NULL; + struct ec_config *list = NULL, *subconfig = NULL; + struct ec_config *list_, *config_; int testres = 0; int ret; + testres |= EC_TEST_CHECK(ec_config_key_is_reserved("id"), + "'id' should be reserved"); + testres |= EC_TEST_CHECK(!ec_config_key_is_reserved("foo"), + "'foo' should not be reserved"); + node = ec_node("empty", EC_NO_ID); if (node == NULL) goto fail; - if (ec_config_schema_validate(baseconfig, - EC_COUNT_OF(baseconfig)) < 0) { + if (ec_config_schema_validate(sch_baseconfig) < 0) { EC_LOG(EC_LOG_ERR, "invalid config schema\n"); goto fail; } - ec_config_schema_dump(stdout, baseconfig, EC_COUNT_OF(baseconfig)); + ec_config_schema_dump(stdout, sch_baseconfig); config = ec_config_dict(); if (config == NULL) goto fail; - if (ec_config_set_schema(config, baseconfig, - EC_COUNT_OF(baseconfig)) < 0) - goto fail; - ret = ec_config_set(config, "bool", ec_config_bool(true)); + ret = ec_config_dict_set(config, "my_bool", ec_config_bool(true)); testres |= EC_TEST_CHECK(ret == 0, "cannot set boolean"); - value = ec_config_get(config, "bool"); + value = ec_config_dict_get(config, "my_bool"); testres |= EC_TEST_CHECK( value != NULL && value->type == EC_CONFIG_TYPE_BOOL && value->boolean == true, "unexpected boolean value"); - ret = ec_config_set(config, "int", ec_config_i64(1234)); + ret = ec_config_dict_set(config, "my_int", ec_config_i64(1234)); testres |= EC_TEST_CHECK(ret == 0, "cannot set int"); - value = ec_config_get(config, "int"); + value = ec_config_dict_get(config, "my_int"); testres |= EC_TEST_CHECK( value != NULL && value->type == EC_CONFIG_TYPE_INT64 && @@ -843,12 +998,12 @@ static int ec_config_testcase(void) "unexpected int value"); testres |= EC_TEST_CHECK( - ec_config_validate(config) == 0, + ec_config_validate(config, sch_baseconfig) == 0, "cannot validate config\n"); - ret = ec_config_set(config, "string", ec_config_string("toto")); + ret = ec_config_dict_set(config, "my_string", ec_config_string("toto")); testres |= EC_TEST_CHECK(ret == 0, "cannot set string"); - value = ec_config_get(config, "string"); + value = ec_config_dict_get(config, "my_string"); testres |= EC_TEST_CHECK( value != NULL && value->type == EC_CONFIG_TYPE_STRING && @@ -863,25 +1018,29 @@ static int ec_config_testcase(void) if (subconfig == NULL) goto fail; - ret = ec_config_set(subconfig, "int", ec_config_i64(1)); + ret = ec_config_dict_set(subconfig, "my_int", ec_config_i64(1)); testres |= EC_TEST_CHECK(ret == 0, "cannot set int"); - value = ec_config_get(subconfig, "int"); + value = ec_config_dict_get(subconfig, "my_int"); testres |= EC_TEST_CHECK( value != NULL && value->type == EC_CONFIG_TYPE_INT64 && value->i64 == 1, "unexpected int value"); - ret = ec_config_set(subconfig, "int2", ec_config_i64(2)); + ret = ec_config_dict_set(subconfig, "my_int2", ec_config_i64(2)); testres |= EC_TEST_CHECK(ret == 0, "cannot set int"); - value = ec_config_get(subconfig, "int2"); + value = ec_config_dict_get(subconfig, "my_int2"); testres |= EC_TEST_CHECK( value != NULL && value->type == EC_CONFIG_TYPE_INT64 && value->i64 == 2, "unexpected int value"); - ret = ec_config_add(list, subconfig); + testres |= EC_TEST_CHECK( + ec_config_validate(subconfig, sch_dict) == 0, + "cannot validate subconfig\n"); + + ret = ec_config_list_add(list, subconfig); subconfig = NULL; /* freed */ testres |= EC_TEST_CHECK(ret == 0, "cannot add in list"); @@ -889,127 +1048,62 @@ static int ec_config_testcase(void) if (subconfig == NULL) goto fail; - ret = ec_config_set(subconfig, "int", ec_config_i64(3)); + ret = ec_config_dict_set(subconfig, "my_int", ec_config_i64(3)); testres |= EC_TEST_CHECK(ret == 0, "cannot set int"); - value = ec_config_get(subconfig, "int"); + value = ec_config_dict_get(subconfig, "my_int"); testres |= EC_TEST_CHECK( value != NULL && value->type == EC_CONFIG_TYPE_INT64 && value->i64 == 3, "unexpected int value"); - ret = ec_config_set(subconfig, "int2", ec_config_i64(4)); + ret = ec_config_dict_set(subconfig, "my_int2", ec_config_i64(4)); testres |= EC_TEST_CHECK(ret == 0, "cannot set int"); - value = ec_config_get(subconfig, "int2"); + value = ec_config_dict_get(subconfig, "my_int2"); testres |= EC_TEST_CHECK( value != NULL && value->type == EC_CONFIG_TYPE_INT64 && value->i64 == 4, "unexpected int value"); - ret = ec_config_add(list, subconfig); + testres |= EC_TEST_CHECK( + ec_config_validate(subconfig, sch_dict) == 0, + "cannot validate subconfig\n"); + + ret = ec_config_list_add(list, subconfig); subconfig = NULL; /* freed */ testres |= EC_TEST_CHECK(ret == 0, "cannot add in list"); - ret = ec_config_set(config, "dictlist", list); + ret = ec_config_dict_set(config, "my_dictlist", list); list = NULL; testres |= EC_TEST_CHECK(ret == 0, "cannot set list"); testres |= EC_TEST_CHECK( - ec_config_validate(config) == 0, + ec_config_validate(config, sch_baseconfig) == 0, "cannot validate config\n"); -#if 0 - /* api */ - config = ec_config(schema); - value = ec_config_bool(true); - ec_config_set(config, "key", value); - value = ec_config_get(config, "key"); - /* check value->type and value->bool */ - - value = ec_config_string("xxx"); - ec_config_set(config, "key", value); - value = ec_config_get(config, "key"); - /* check value->type and value->string */ - - list = ec_config_list(); - value = ec_config_string("xxx"); - ec_config_add(list, value); - value = ec_config_string("yyy"); - ec_config_add(list, value); - value = ec_config_remove(list, 0); - ec_config_set(config, "key", list); - -#endif - -#if 0 - value.type = EC_CONFIG_TYPE_NODE; - value.node = ec_node_clone(node); - ret = ec_config_set(config, "node", value); - testres |= EC_TEST_CHECK(ret == 0, "cannot set node"); - pvalue = ec_config_get(config, "node"); - testres |= EC_TEST_CHECK( - pvalue != NULL && - ec_config_cmp(pvalue, &value) == 0, - "unexpected node value"); + list_ = ec_config_dict_get(config, "my_dictlist"); + for (config_ = ec_config_list_first(list_); config_ != NULL; + config_ = ec_config_list_next(list_, config_)) { + ec_config_dump(stdout, config_); + } - subconfig = ec_config(dict, EC_COUNT_OF(dict)); - if (subconfig == NULL) - goto fail; + ec_config_dump(stdout, config); - value.type = EC_CONFIG_TYPE_INT64; - value.i64 = 4321; - ret = ec_config_set(subconfig, "int", value); - testres |= EC_TEST_CHECK(ret == 0, "cannot set int"); - pvalue = ec_config_get(subconfig, "int"); + config2 = ec_config_dup(config); + testres |= EC_TEST_CHECK(config2 != NULL, "cannot duplicate config"); testres |= EC_TEST_CHECK( - pvalue != NULL && - ec_config_cmp(pvalue, &value) == 0, - "unexpected int value"); + ec_config_cmp(config, config2) == 0, + "fail to compare config"); + ec_config_free(config2); + config2 = NULL; - value.type = EC_CONFIG_TYPE_DICT; - value.dict = subconfig; - subconfig = NULL; /* will be freed when freeing config */ - ret = ec_config_set(config, "dict", value); - testres |= EC_TEST_CHECK(ret == 0, "cannot set dict"); - pvalue = ec_config_get(config, "dict"); - testres |= EC_TEST_CHECK( - pvalue != NULL && - ec_config_cmp(pvalue, &value) == 0, - "unexpected dict value"); - - value.type = EC_CONFIG_TYPE_INT64; - value.i64 = 4321; - pvalue = ec_config_get( - ec_config_get(config, "dict")->dict, "int"); + /* remove the first element */ + ec_config_list_del(list_, ec_config_list_first(list_)); testres |= EC_TEST_CHECK( - pvalue != NULL && - ec_config_cmp(pvalue, &value) == 0, - "unexpected int value"); + ec_config_validate(config, sch_baseconfig) == 0, + "cannot validate config\n"); - value.type = EC_CONFIG_TYPE_INT64; - value.i64 = 1; - ret = ec_config_add(config, "intlist", value); - testres |= EC_TEST_CHECK(ret == 0, "cannot add int in list"); - value.type = EC_CONFIG_TYPE_INT64; - value.i64 = 2; - ret = ec_config_add(config, "intlist", value); - testres |= EC_TEST_CHECK(ret == 0, "cannot add int in list"); - value.type = EC_CONFIG_TYPE_INT64; - value.i64 = 3; - ret = ec_config_add(config, "intlist", value); - testres |= EC_TEST_CHECK(ret == 0, "cannot add int in list"); - - value.type = EC_CONFIG_TYPE_INT64; - value.i64 = 4321; - ret = ec_config_set(config, "invalid", value); - testres |= EC_TEST_CHECK(ret < 0, - "should not be able to set invalid key"); - pvalue = ec_config_get(config, "invalid"); - testres |= EC_TEST_CHECK(pvalue == NULL, - "invalid key returned a value"); - -#endif ec_config_dump(stdout, config); ec_config_free(list); @@ -1024,6 +1118,7 @@ fail: ec_config_free(list); ec_config_free(subconfig); ec_config_free(config); + ec_config_free(config2); ec_keyval_free(dict); ec_node_free(node);