path FEATURE variables instead of values
Supported now for node-instance-identifier.
diff --git a/src/tree_data_new.c b/src/tree_data_new.c
index 864fc9e..d647be3 100644
--- a/src/tree_data_new.c
+++ b/src/tree_data_new.c
@@ -134,10 +134,14 @@
}
LY_ERR
-lyd_create_list(const struct lysc_node *schema, const struct ly_path_predicate *predicates, struct lyd_node **node)
+lyd_create_list(const struct lysc_node *schema, const struct ly_path_predicate *predicates, const struct lyxp_var *vars,
+ struct lyd_node **node)
{
LY_ERR ret = LY_SUCCESS;
struct lyd_node *list = NULL, *key;
+ const struct lyd_value *value;
+ struct lyd_value val = {0};
+ struct lyxp_var *var;
LY_ARRAY_COUNT_TYPE u;
assert((schema->nodetype == LYS_LIST) && !(schema->flags & LYS_KEYLESS));
@@ -149,7 +153,31 @@
/* create and insert all the keys */
LY_ARRAY_FOR(predicates, u) {
- LY_CHECK_GOTO(ret = lyd_create_term2(predicates[u].key, &predicates[u].value, &key), cleanup);
+ if (predicates[u].type == LY_PATH_PREDTYPE_LIST_VAR) {
+ /* find the var */
+ if ((ret = lyxp_vars_find(schema->module->ctx, vars, predicates[u].variable, 0, &var))) {
+ goto cleanup;
+ }
+
+ /* store the value */
+ LOG_LOCSET(predicates[u].key, NULL, NULL, NULL);
+ ret = lyd_value_store(schema->module->ctx, &val, ((struct lysc_node_leaf *)predicates[u].key)->type,
+ var->value, strlen(var->value), NULL, LY_VALUE_JSON, NULL, LYD_HINT_DATA, predicates[u].key, NULL);
+ LOG_LOCBACK(1, 0, 0, 0);
+ LY_CHECK_GOTO(ret, cleanup);
+
+ value = &val;
+ } else {
+ assert(predicates[u].type == LY_PATH_PREDTYPE_LIST);
+ value = &predicates[u].value;
+ }
+
+ ret = lyd_create_term2(predicates[u].key, value, &key);
+ if (val.realtype) {
+ val.realtype->plugin->free(schema->module->ctx, &val);
+ memset(&val, 0, sizeof val);
+ }
+ LY_CHECK_GOTO(ret, cleanup);
lyd_insert_node(list, NULL, key, 0);
}
@@ -172,7 +200,6 @@
LY_ERR ret = LY_SUCCESS;
struct lyxp_expr *expr = NULL;
uint32_t exp_idx = 0;
- enum ly_path_pred_type pred_type = 0;
struct ly_path_predicate *predicates = NULL;
LOG_LOCSET(schema, NULL, NULL, NULL);
@@ -183,15 +210,15 @@
/* compile them */
LY_CHECK_GOTO(ret = ly_path_compile_predicate(schema->module->ctx, NULL, NULL, schema, expr, &exp_idx, LY_VALUE_JSON,
- NULL, &predicates, &pred_type), cleanup);
+ NULL, &predicates), cleanup);
/* create the list node */
- LY_CHECK_GOTO(ret = lyd_create_list(schema, predicates, node), cleanup);
+ LY_CHECK_GOTO(ret = lyd_create_list(schema, predicates, NULL, node), cleanup);
cleanup:
LOG_LOCBACK(1, 0, 0, 0);
lyxp_expr_free(schema->module->ctx, expr);
- ly_path_predicates_free(schema->module->ctx, pred_type, predicates);
+ ly_path_predicates_free(schema->module->ctx, predicates);
return ret;
}
@@ -1320,18 +1347,19 @@
schema = path[u].node;
if (lysc_is_dup_inst_list(schema)) {
- if (path[u].pred_type == LY_PATH_PREDTYPE_NONE) {
+ if (!path[u].predicates) {
/* creating a new key-less list or state leaf-list instance */
create = 1;
new_count = u;
- } else if (path[u].pred_type != LY_PATH_PREDTYPE_POSITION) {
+ } else if (path[u].predicates[0].type != LY_PATH_PREDTYPE_POSITION) {
LOG_LOCSET(schema, NULL, NULL, NULL);
LOGVAL(schema->module->ctx, LYVE_XPATH, "Invalid predicate for %s \"%s\" in path \"%s\".",
lys_nodetype2str(schema->nodetype), schema->name, str_path);
LOG_LOCBACK(1, 0, 0, 0);
return LY_EINVAL;
}
- } else if ((schema->nodetype == LYS_LIST) && (path[u].pred_type != LY_PATH_PREDTYPE_LIST)) {
+ } else if ((schema->nodetype == LYS_LIST) &&
+ (!path[u].predicates || (path[u].predicates[0].type != LY_PATH_PREDTYPE_LIST))) {
if ((u < LY_ARRAY_COUNT(path) - 1) || !(options & LYD_NEW_PATH_OPAQ)) {
LOG_LOCSET(schema, NULL, NULL, NULL);
LOGVAL(schema->module->ctx, LYVE_XPATH, "Predicate missing for %s \"%s\" in path \"%s\".",
@@ -1339,7 +1367,8 @@
LOG_LOCBACK(1, 0, 0, 0);
return LY_EINVAL;
} /* else creating an opaque list */
- } else if ((schema->nodetype == LYS_LEAFLIST) && (path[u].pred_type != LY_PATH_PREDTYPE_LEAFLIST)) {
+ } else if ((schema->nodetype == LYS_LEAFLIST) &&
+ (!path[u].predicates || (path[u].predicates[0].type != LY_PATH_PREDTYPE_LEAFLIST))) {
r = LY_SUCCESS;
if (options & LYD_NEW_PATH_OPAQ) {
r = lyd_value_validate(NULL, schema, value, value_len, NULL, NULL, NULL);
@@ -1351,8 +1380,8 @@
++((struct lysc_type *)val.realtype)->refcount;
/* store the new predicate so that it is used when searching for this instance */
- path[u].pred_type = LY_PATH_PREDTYPE_LEAFLIST;
LY_ARRAY_NEW_RET(schema->module->ctx, path[u].predicates, pred, LY_EMEM);
+ pred->type = LY_PATH_PREDTYPE_LEAFLIST;
pred->value = val;
} /* else we have opaq flag and the value is not valid, leave no predicate and then create an opaque node */
}
@@ -1442,7 +1471,7 @@
/* try to find any existing nodes in the path */
if (parent) {
- ret = ly_path_eval_partial(p, parent, &path_idx, &node);
+ ret = ly_path_eval_partial(p, parent, NULL, &path_idx, &node);
if (ret == LY_SUCCESS) {
if (orig_count == LY_ARRAY_COUNT(p)) {
/* the node exists, are we supposed to update it or is it just a default? */
@@ -1487,15 +1516,14 @@
if (lysc_is_dup_inst_list(schema)) {
/* create key-less list instance */
LY_CHECK_GOTO(ret = lyd_create_inner(schema, &node), cleanup);
- } else if ((options & LYD_NEW_PATH_OPAQ) && (p[path_idx].pred_type == LY_PATH_PREDTYPE_NONE)) {
+ } else if ((options & LYD_NEW_PATH_OPAQ) && !p[path_idx].predicates) {
/* creating opaque list without keys */
LY_CHECK_GOTO(ret = lyd_create_opaq(ctx, schema->name, strlen(schema->name), NULL, 0,
schema->module->name, strlen(schema->module->name), NULL, 0, NULL, LY_VALUE_JSON, NULL,
LYD_NODEHINT_LIST, &node), cleanup);
} else {
/* create standard list instance */
- assert(p[path_idx].pred_type == LY_PATH_PREDTYPE_LIST);
- LY_CHECK_GOTO(ret = lyd_create_list(schema, p[path_idx].predicates, &node), cleanup);
+ LY_CHECK_GOTO(ret = lyd_create_list(schema, p[path_idx].predicates, NULL, &node), cleanup);
}
break;
case LYS_CONTAINER:
@@ -1505,7 +1533,8 @@
LY_CHECK_GOTO(ret = lyd_create_inner(schema, &node), cleanup);
break;
case LYS_LEAFLIST:
- if ((options & LYD_NEW_PATH_OPAQ) && (p[path_idx].pred_type != LY_PATH_PREDTYPE_LEAFLIST)) {
+ if ((options & LYD_NEW_PATH_OPAQ) &&
+ (!p[path_idx].predicates || (p[path_idx].predicates[0].type != LY_PATH_PREDTYPE_LEAFLIST))) {
/* we have not checked this only for dup-inst lists, otherwise it must be opaque */
r = LY_EVALID;
if (lysc_is_dup_inst_list(schema)) {
@@ -1522,13 +1551,13 @@
}
/* get value to set */
- if (p[path_idx].pred_type == LY_PATH_PREDTYPE_LEAFLIST) {
+ if (p[path_idx].predicates && (p[path_idx].predicates[0].type == LY_PATH_PREDTYPE_LEAFLIST)) {
val = &p[path_idx].predicates[0].value;
}
/* create a leaf-list instance */
if (val) {
- LY_CHECK_GOTO(ret = lyd_create_term2(schema, &p[path_idx].predicates[0].value, &node), cleanup);
+ LY_CHECK_GOTO(ret = lyd_create_term2(schema, val, &node), cleanup);
} else {
LY_CHECK_GOTO(ret = lyd_create_term(schema, value, value_len, NULL, format, NULL, LYD_HINT_DATA,
NULL, &node), cleanup);