data tree REFACTOR remove lys_value_validate
Its functionality was added into lyd_value_validate.
diff --git a/doc/transition.dox b/doc/transition.dox
index a466f78..5374691 100644
--- a/doc/transition.dox
+++ b/doc/transition.dox
@@ -180,7 +180,6 @@
* - | ::lys_find_child() | Helpers wrapper around ::lys_getnext().
* - | ::lys_getnext_ext() | Alternative to ::lys_getnext() allowing processing schema trees inside extension instances.
* - | ::lys_nodetype2str() | New functionality.
- * - | ::lys_value_validate() | Supplement functionality to ::lyd_value_validate().
* lys_is_key() | ::lysc_is_key() | Renamed to connect with the compiled schema tree.
* - | ::lysc_is_userordered() | Added functionality to simplify the examination of generic compiled schema nodes.
* - | ::lysc_is_np_cont() | ^
diff --git a/src/parser_json.c b/src/parser_json.c
index 6e6d752..bea4003 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -355,7 +355,7 @@
goto cleanup;
}
- ret = _lys_value_validate(NULL, snode, jsonctx->value, jsonctx->value_len, LY_PREF_JSON, NULL);
+ ret = lys_value_validate(NULL, snode, jsonctx->value, jsonctx->value_len, LY_PREF_JSON, NULL);
LY_CHECK_GOTO(ret, cleanup);
/* key with a valid value, remove from the set */
@@ -468,7 +468,7 @@
break;
}
- if (_lys_value_validate(NULL, snode, jsonctx->value, jsonctx->value_len, LY_PREF_JSON, NULL)) {
+ if (lys_value_validate(NULL, snode, jsonctx->value, jsonctx->value_len, LY_PREF_JSON, NULL)) {
ret = LY_ENOT;
}
break;
diff --git a/src/parser_xml.c b/src/parser_xml.c
index decbaf4..de48509 100644
--- a/src/parser_xml.c
+++ b/src/parser_xml.c
@@ -248,7 +248,7 @@
assert(xmlctx->status == LYXML_ELEM_CONTENT);
if (i < key_set.count) {
/* validate the value */
- r = _lys_value_validate(NULL, snode, xmlctx->value, xmlctx->value_len, LY_PREF_XML, &xmlctx->ns);
+ r = lys_value_validate(NULL, snode, xmlctx->value, xmlctx->value_len, LY_PREF_XML, &xmlctx->ns);
if (!r) {
/* key with a valid value, remove from the set */
ly_set_rm_index(&key_set, i, NULL);
@@ -346,7 +346,7 @@
if ((*snode)->nodetype & LYD_NODE_TERM) {
/* value may not be valid in which case we parse it as an opaque node */
- if (_lys_value_validate(NULL, *snode, xmlctx->value, xmlctx->value_len, LY_PREF_XML, &xmlctx->ns)) {
+ if (lys_value_validate(NULL, *snode, xmlctx->value, xmlctx->value_len, LY_PREF_XML, &xmlctx->ns)) {
*snode = NULL;
}
} else {
diff --git a/src/tree_data.c b/src/tree_data.c
index 1a8bf2b..3013c0a 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -113,7 +113,7 @@
}
LY_ERR
-_lys_value_validate(const struct ly_ctx *ctx, const struct lysc_node *node, const char *value, size_t value_len,
+lys_value_validate(const struct ly_ctx *ctx, const struct lysc_node *node, const char *value, size_t value_len,
LY_PREFIX_FORMAT format, void *prefix_data)
{
LY_ERR rc = LY_SUCCESS;
@@ -152,14 +152,8 @@
}
API LY_ERR
-lys_value_validate(const struct ly_ctx *ctx, const struct lysc_node *node, const char *value, size_t value_len)
-{
- return _lys_value_validate(ctx, node, value, value_len, LY_PREF_JSON, NULL);
-}
-
-API LY_ERR
-lyd_value_validate(const struct ly_ctx *ctx, const struct lyd_node_term *node, const char *value, size_t value_len,
- const struct lyd_node *tree, const struct lysc_type **realtype)
+lyd_value_validate(const struct ly_ctx *ctx, const struct lysc_node *schema, const char *value, size_t value_len,
+ const struct lyd_node *ctx_node, const struct lysc_type **realtype, const char **canonical)
{
LY_ERR rc;
struct ly_err_item *err = NULL;
@@ -167,44 +161,65 @@
struct lyd_value val = {0};
ly_bool stored = 0;
- LY_CHECK_ARG_RET(ctx, node, value, LY_EINVAL);
+ LY_CHECK_ARG_RET(ctx, schema, value, LY_EINVAL);
- type = ((struct lysc_node_leaf *)node->schema)->type;
+ type = ((struct lysc_node_leaf *)schema)->type;
+
/* store */
- rc = type->plugin->store(ctx ? ctx : LYD_CTX(node), type, value, value_len, 0, LY_PREF_JSON, NULL,
- LYD_HINT_DATA, node->schema, &val, NULL, &err);
- if (rc == LY_EINCOMPLETE) {
+ rc = type->plugin->store(ctx ? ctx : schema->module->ctx, type, value, value_len, 0, LY_PREF_JSON, NULL,
+ LYD_HINT_DATA, schema, &val, NULL, &err);
+ if (!rc || (rc == LY_EINCOMPLETE)) {
stored = 1;
+ }
+ if (ctx_node && (rc == LY_EINCOMPLETE)) {
/* resolve */
- rc = type->plugin->validate(ctx ? ctx : LYD_CTX(node), type, &node->node, tree, &val, &err);
+ rc = type->plugin->validate(ctx ? ctx : schema->module->ctx, type, ctx_node, ctx_node, &val, &err);
}
- if (rc) {
- if (err) {
- if (ctx) {
- LOG_LOCSET(NULL, &node->node, NULL, NULL);
- LOGVAL(ctx, err->vecode, err->msg);
- LOG_LOCBACK(0, 1, 0, 0);
+ if (rc && (rc != LY_EINCOMPLETE) && err) {
+ if (ctx) {
+ /* log error */
+ if (err->path) {
+ LOG_LOCSET(NULL, NULL, err->path, NULL);
+ } else if (ctx_node) {
+ LOG_LOCSET(NULL, ctx_node, NULL, NULL);
+ } else {
+ LOG_LOCSET(schema, NULL, NULL, NULL);
}
- ly_err_free(err);
+ LOGVAL(ctx, err->vecode, err->msg);
+ if (err->path) {
+ LOG_LOCBACK(0, 0, 1, 0);
+ } else if (ctx_node) {
+ LOG_LOCBACK(0, 1, 0, 0);
+ } else {
+ LOG_LOCBACK(1, 0, 0, 0);
+ }
}
- if (stored) {
- type->plugin->free(ctx ? ctx : LYD_CTX(node), &val);
- }
- return rc;
+ ly_err_free(err);
}
- if (realtype) {
- if (val.realtype->basetype == LY_TYPE_UNION) {
- *realtype = val.subvalue->value.realtype;
- } else {
- *realtype = val.realtype;
+ if (!rc || (rc == LY_EINCOMPLETE)) {
+ if (realtype) {
+ /* return realtype */
+ if (val.realtype->basetype == LY_TYPE_UNION) {
+ *realtype = val.subvalue->value.realtype;
+ } else {
+ *realtype = val.realtype;
+ }
+ }
+
+ if (canonical) {
+ /* return canonical value */
+ lydict_insert(ctx ? ctx : schema->module->ctx, val.canonical, 0, canonical);
}
}
- type->plugin->free(ctx ? ctx : LYD_CTX(node), &val);
- return LY_SUCCESS;
+ if (stored) {
+ /* free value */
+ type->plugin->free(ctx ? ctx : schema->module->ctx, &val);
+ }
+ return rc;
}
API LY_ERR
@@ -1587,7 +1602,7 @@
r = LY_SUCCESS;
if (options & LYD_NEW_PATH_OPAQ) {
- r = lys_value_validate(NULL, schema, value, strlen(value));
+ r = lys_value_validate(NULL, schema, value, strlen(value), LY_PREF_JSON, NULL);
}
if (!r) {
/* store the new predicate */
@@ -1772,7 +1787,7 @@
r = LY_SUCCESS;
if (options & LYD_NEW_PATH_OPAQ) {
- r = lys_value_validate(NULL, schema, value, strlen(value));
+ r = lys_value_validate(NULL, schema, value, strlen(value), LY_PREF_JSON, NULL);
}
if (!r) {
ret = lyd_create_term(schema, value, strlen(value), NULL, LY_PREF_JSON, NULL, LYD_HINT_DATA, NULL, &node);
diff --git a/src/tree_data.h b/src/tree_data.h
index 9414baf..c4c8795 100644
--- a/src/tree_data.h
+++ b/src/tree_data.h
@@ -1529,23 +1529,21 @@
*
* The given node is not modified in any way - it is just checked if the @p value can be set to the node.
*
- * If there is no data node instance and you are fine with checking just the type's restrictions without the
- * data tree context (e.g. for the case of require-instance restriction), use ::lys_value_validate().
- *
* @param[in] ctx libyang context for logging (function does not log errors when @p ctx is NULL)
- * @param[in] node Data node for the @p value.
+ * @param[in] schema Schema node of the @p value.
* @param[in] value String value to be checked, it is expected to be in JSON format.
* @param[in] value_len Length of the given @p value (mandatory).
- * @param[in] tree Data tree (e.g. when validating RPC/Notification) where the required data instance (leafref target,
- * instance-identifier) can be placed. NULL in case the data tree is not yet complete,
- * then LY_EINCOMPLETE can be returned.
- * @param[out] realtype Optional real type of the value.
+ * @param[in] ctx_node Optional data tree context node for the value (leafref target, instance-identifier).
+ * If not set and is required for the validation to complete, ::LY_EINCOMPLETE is be returned.
+ * @param[out] realtype Optional real type of @p value.
+ * @param[out] canonical Optional canonical value of @p value (in the dictionary).
* @return LY_SUCCESS on success
- * @return LY_EINCOMPLETE in case the @p trees is not provided and it was needed to finish the validation (e.g. due to require-instance).
+ * @return LY_EINCOMPLETE in case the @p ctx_node is not provided and it was needed to finish the validation
+ * (e.g. due to require-instance).
* @return LY_ERR value if an error occurred.
*/
-LY_ERR lyd_value_validate(const struct ly_ctx *ctx, const struct lyd_node_term *node, const char *value, size_t value_len,
- const struct lyd_node *tree, const struct lysc_type **realtype);
+LY_ERR lyd_value_validate(const struct ly_ctx *ctx, const struct lysc_node *schema, const char *value, size_t value_len,
+ const struct lyd_node *ctx_node, const struct lysc_type **realtype, const char **canonical);
/**
* @brief Compare the node's value with the given string value. The string value is first validated according to
diff --git a/src/tree_data_internal.h b/src/tree_data_internal.h
index e0f0149..b7d2e2e 100644
--- a/src/tree_data_internal.h
+++ b/src/tree_data_internal.h
@@ -331,8 +331,23 @@
LY_ERR lyd_value_validate_incomplete(const struct ly_ctx *ctx, const struct lysc_type *type, struct lyd_value *val,
const struct lyd_node *ctx_node, const struct lyd_node *tree);
-/* generic function lys_value_validate */
-LY_ERR _lys_value_validate(const struct ly_ctx *ctx, const struct lysc_node *node, const char *value, size_t value_len,
+/**
+ * @brief Check type restrictions applicable to the particular leaf/leaf-list with the given string @p value coming
+ * from a schema.
+ *
+ * This function check just the type's restriction, if you want to check also the data tree context (e.g. in case of
+ * require-instance restriction), use ::lyd_value_validate().
+ *
+ * @param[in] ctx libyang context for logging (function does not log errors when @p ctx is NULL)
+ * @param[in] node Schema node for the @p value.
+ * @param[in] value String value to be checked, expected to be in JSON format.
+ * @param[in] value_len Length of the given @p value (mandatory).
+ * @param[in] format Value prefix format.
+ * @param[in] prefix_data Format-specific data for resolving any prefixes (see ::ly_resolve_prefix).
+ * @return LY_SUCCESS on success
+ * @return LY_ERR value if an error occurred.
+ */
+LY_ERR lys_value_validate(const struct ly_ctx *ctx, const struct lysc_node *node, const char *value, size_t value_len,
LY_PREFIX_FORMAT format, void *prefix_data);
/**
diff --git a/src/tree_schema.h b/src/tree_schema.h
index c6f6bcd..70913cf 100644
--- a/src/tree_schema.h
+++ b/src/tree_schema.h
@@ -101,7 +101,6 @@
* - ::lys_getnext()
* - ::lys_nodetype2str()
* - ::lys_set_implemented()
- * - ::lys_value_validate()
*
* - ::lysc_has_when()
*
@@ -2432,21 +2431,6 @@
LY_ERR lys_set_implemented(struct lys_module *mod, const char **features);
/**
- * @brief Check type restrictions applicable to the particular leaf/leaf-list with the given string @p value.
- *
- * This function check just the type's restriction, if you want to check also the data tree context (e.g. in case of
- * require-instance restriction), use ::lyd_value_validate().
- *
- * @param[in] ctx libyang context for logging (function does not log errors when @p ctx is NULL)
- * @param[in] node Schema node for the @p value.
- * @param[in] value String value to be checked, expected to be in JSON format.
- * @param[in] value_len Length of the given @p value (mandatory).
- * @return LY_SUCCESS on success
- * @return LY_ERR value if an error occurred.
- */
-LY_ERR lys_value_validate(const struct ly_ctx *ctx, const struct lysc_node *node, const char *value, size_t value_len);
-
-/**
* @brief Stringify schema nodetype.
*
* @param[in] nodetype Nodetype to stringify.
diff --git a/tests/utests/data/test_types.c b/tests/utests/data/test_types.c
index 607be2a..3b5d784 100644
--- a/tests/utests/data/test_types.c
+++ b/tests/utests/data/test_types.c
@@ -814,18 +814,18 @@
CHECK_PARSE_LYD(data, tree);
/* key-predicate */
data = "/types:list2[id='a'][value='b']/id";
- assert_int_equal(LY_ENOTFOUND, lyd_value_validate(UTEST_LYCTX, (const struct lyd_node_term *)tree->prev, data, strlen(data),
- tree, NULL));
+ assert_int_equal(LY_ENOTFOUND, lyd_value_validate(UTEST_LYCTX, tree->prev->schema, data, strlen(data), tree->prev,
+ NULL, NULL));
CHECK_LOG_CTX("Invalid instance-identifier \"/types:list2[id='a'][value='b']/id\" value - required instance not found.", "Data location /types:inst.");
/* leaf-list-predicate */
data = "/types:leaflisttarget[.='c']";
- assert_int_equal(LY_ENOTFOUND, lyd_value_validate(UTEST_LYCTX, (const struct lyd_node_term *)tree->prev, data, strlen(data),
- tree, NULL));
+ assert_int_equal(LY_ENOTFOUND, lyd_value_validate(UTEST_LYCTX, tree->prev->schema, data, strlen(data), tree->prev,
+ NULL, NULL));
CHECK_LOG_CTX("Invalid instance-identifier \"/types:leaflisttarget[.='c']\" value - required instance not found.", "Data location /types:inst.");
/* position predicate */
data = "/types:list_keyless[4]";
- assert_int_equal(LY_ENOTFOUND, lyd_value_validate(UTEST_LYCTX, (const struct lyd_node_term *)tree->prev, data, strlen(data),
- tree, NULL));
+ assert_int_equal(LY_ENOTFOUND, lyd_value_validate(UTEST_LYCTX, tree->prev->schema, data, strlen(data), tree->prev,
+ NULL, NULL));
CHECK_LOG_CTX("Invalid instance-identifier \"/types:list_keyless[4]\" value - required instance not found.", "Data location /types:inst.");
lyd_free_all(tree);
diff --git a/tools/re/main.c b/tools/re/main.c
index 8583e73..701b0a1 100644
--- a/tools/re/main.c
+++ b/tools/re/main.c
@@ -269,7 +269,7 @@
}
/* check the value */
- match = lys_value_validate(ctx, mod->compiled->data, str, strlen(str));
+ match = lyd_value_validate(ctx, mod->compiled->data, str, strlen(str), NULL, NULL, NULL);
if (verbose) {
for (i = 0; i < patterns_count; i++) {