diff --git a/src/context.c b/src/context.c index 30b159913..0c410190b 100644 --- a/src/context.c +++ b/src/context.c @@ -251,9 +251,9 @@ ly_ctx_ht_leafref_links_equal_cb(void *val1_p, void *val2_p, ly_bool UNUSED(mod) } /** - * @brief Callback for freeing leafref links hash table values. + * @brief Callback for freeing leafref links recorcd internal resources. * - * @param[in] val_p Pointer to a pointer to a leafref links item to free with all the siblings. + * @param[in] val_p Pointer to leafref links record */ static void ly_ctx_ht_leafref_links_rec_free(void *val_p) diff --git a/src/context.h b/src/context.h index 50476c86c..e516fef7b 100644 --- a/src/context.h +++ b/src/context.h @@ -200,8 +200,8 @@ struct ly_ctx; #define LY_CTX_LEAFREF_EXTENDED 0x0200 /**< By default, path attribute of leafref accepts only path as defined in RFC 7950. By using this option, the path attribute will also allow using XPath functions as deref() */ #define LY_CTX_LEAFREF_LINKING 0x0400 /**< Link leafref nodes with its target during validation. It also enables usage of - [get_record](@ref lyd_get_term_nodes_ext_record) and - [link_tree](@ref lyd_link_leafref_node_tree) APIs. */ + [lyd_leafref_get_links](@ref lyd_leafref_get_links) and + [lyd_leafref_link_node_tree](@ref lyd_leafref_link_node_tree) APIs. */ /** @} contextoptions */ diff --git a/src/parser_data.h b/src/parser_data.h index ccaa387dc..feedb1407 100644 --- a/src/parser_data.h +++ b/src/parser_data.h @@ -196,6 +196,7 @@ struct ly_in; * already a case and another one was added, the previous one is silently auto-deleted. Otherwise (if data from 2 or * more cases were created) a validation error is raised, * - default values are added. + * * @{ */ #define LYD_VALIDATE_NO_STATE 0x0001 /**< Consider state data not allowed and raise an error if they are found. diff --git a/src/tree_data.c b/src/tree_data.c index 1bf5d0f14..3042b8099 100644 --- a/src/tree_data.c +++ b/src/tree_data.c @@ -3273,16 +3273,7 @@ lyd_get_value(const struct lyd_node *node) return NULL; } -/** - * @brief Gets or creates the leafref links record. - * - * @param[in] node The term data node. - * @param[out] record The leafref links record. - * @param[in] create Whether to create record if not exists. - * @return LY_SUCCESS on success. - * @return LY_ERR value on error. - */ -static LY_ERR +LY_ERR lyd_get_or_create_leafref_links_record(const struct lyd_node_term *node, struct lyd_leafref_links_rec **record, ly_bool create) { struct ly_ht *ht; @@ -3316,9 +3307,16 @@ lyd_get_or_create_leafref_links_record(const struct lyd_node_term *node, struct } LIBYANG_API_DEF LY_ERR -lyd_get_leafref_links(const struct lyd_node_term *node, struct lyd_leafref_links_rec **record) +lyd_leafref_get_links(const struct lyd_node_term *node, const struct lyd_leafref_links_rec **record) { - return lyd_get_or_create_leafref_links_record(node, record, 0); + struct lyd_leafref_links_rec *record2 = NULL; + LY_ERR ret; + + assert(record); + + ret = lyd_get_or_create_leafref_links_record(node, &record2, 0); + *record = record2; + return ret; } LY_ERR @@ -3350,7 +3348,7 @@ lyd_link_leafref_node(const struct lyd_node_term *node, const struct lyd_node_te } LIBYANG_API_DEF LY_ERR -lyd_link_leafref_node_tree(const struct lyd_node *tree) +lyd_leafref_link_node_tree(const struct lyd_node *tree) { const struct lyd_node *sibling, *elem; struct lyd_node *target; @@ -3402,7 +3400,7 @@ lyd_unlink_leafref_node(const struct lyd_node_term *node, const struct lyd_node_ return LY_EDENIED; } - ret = lyd_get_leafref_links(node, &rec); + ret = lyd_get_or_create_leafref_links_record(node, &rec, 0); if (ret == LY_SUCCESS) { LY_ARRAY_REMOVE_VALUE(rec->leafref_nodes, leafref_node); if ((LY_ARRAY_COUNT(rec->leafref_nodes) == 0) && (rec->target_node == NULL)) { @@ -3412,7 +3410,7 @@ lyd_unlink_leafref_node(const struct lyd_node_term *node, const struct lyd_node_ return ret; } - ret = lyd_get_leafref_links(leafref_node, &rec); + ret = lyd_get_or_create_leafref_links_record(leafref_node, &rec, 0); if (ret == LY_SUCCESS) { rec->target_node = NULL; if ((LY_ARRAY_COUNT(rec->leafref_nodes) == 0) && (rec->target_node == NULL)) { diff --git a/src/tree_data.h b/src/tree_data.h index 1be2aff54..9277bbe89 100644 --- a/src/tree_data.h +++ b/src/tree_data.h @@ -1003,10 +1003,11 @@ struct lyd_node_opaq { struct lyd_leafref_links_rec { const struct lyd_node_term *node; /** pointer to the data node itself */ const struct lyd_node_term **leafref_nodes; /** list of the leafref pointing to this data node [sized array](@ref sizedarrays)), - By default it is empty. It is filled automatically by validation - function of leafref nodes. It can also be populated based on manual request - using [link api](@ref lyd_link_leafref_node_tree). Freeing of the resources - is automatic. */ + By default it is empty. It is filled automatically by validation function of + leafref nodes, which are valid and are not using 'require-instance false'. + It can also be populated based on manual request using + [link api](@ref lyd_leafref_link_node_tree). Freeing of the resources is + automatic. */ const struct lyd_node_term *target_node; /** pointer to leafref target data node, by default is NULL. The logic is the same as for [leafref_nodes](@ref leafref_nodes) and is filled only for leafrefs */ @@ -2727,7 +2728,7 @@ LIBYANG_API_DECL LY_ERR ly_time_ts2str(const struct timespec *ts, char **str); * @return LY_SUCCESS on success. * @return LY_ERR value on error. */ -LIBYANG_API_DECL LY_ERR lyd_get_leafref_links(const struct lyd_node_term *node, struct lyd_leafref_links_rec **record); +LIBYANG_API_DECL LY_ERR lyd_leafref_get_links(const struct lyd_node_term *node, const struct lyd_leafref_links_rec **record); /** * @brief Traverse through data tree including root node siblings and adds leafrefs links to the given nodes @@ -2738,7 +2739,7 @@ LIBYANG_API_DECL LY_ERR lyd_get_leafref_links(const struct lyd_node_term *node, * @return LY_SUCCESS on success. * @return LY_ERR value on error. */ -LIBYANG_API_DECL LY_ERR lyd_link_leafref_node_tree(const struct lyd_node *tree); +LIBYANG_API_DECL LY_ERR lyd_leafref_link_node_tree(const struct lyd_node *tree); #ifdef __cplusplus } diff --git a/src/tree_data_free.c b/src/tree_data_free.c index 790022ff9..100cf4954 100644 --- a/src/tree_data_free.c +++ b/src/tree_data_free.c @@ -148,7 +148,7 @@ lyd_free_leafref_links_rec(struct lyd_leafref_links_rec *rec) /* remove stored leafref nodes */ LY_ARRAY_FOR(rec->leafref_nodes, u) { - if (lyd_get_leafref_links(rec->leafref_nodes[u], &leafref_rec) == LY_SUCCESS) { + if (lyd_get_or_create_leafref_links_record(rec->leafref_nodes[u], &leafref_rec, 0) == LY_SUCCESS) { leafref_rec->target_node = NULL; if ((LY_ARRAY_COUNT(leafref_rec->leafref_nodes) == 0) && (leafref_rec->target_node == NULL)) { lyd_free_leafref_nodes(rec->leafref_nodes[u]); @@ -172,7 +172,7 @@ lyd_free_leafref_nodes(const struct lyd_node_term *node) assert(node); - if (lyd_get_leafref_links(node, &rec) != LY_SUCCESS) { + if (lyd_get_or_create_leafref_links_record(node, &rec, 0) != LY_SUCCESS) { return; } diff --git a/src/tree_data_internal.h b/src/tree_data_internal.h index 244c6f835..d63959122 100644 --- a/src/tree_data_internal.h +++ b/src/tree_data_internal.h @@ -605,6 +605,17 @@ void lyd_free_leafref_links_rec(struct lyd_leafref_links_rec *rec); */ void lyd_free_leafref_nodes(const struct lyd_node_term *node); +/** + * @brief Gets or creates the leafref links record. + * + * @param[in] node The term data node. + * @param[out] record The leafref links record. + * @param[in] create Whether to create record if not exists. + * @return LY_SUCCESS on success. + * @return LY_ERR value on error. + */ +LY_ERR lyd_get_or_create_leafref_links_record(const struct lyd_node_term *node, struct lyd_leafref_links_rec **record, ly_bool create); + /** * @brief Adds links between leafref adn data node. * diff --git a/src/tree_edit.h b/src/tree_edit.h index e9eb2cf1b..049bc026e 100644 --- a/src/tree_edit.h +++ b/src/tree_edit.h @@ -247,6 +247,7 @@ void *ly_realloc(void *ptr, size_t size); memmove(&(ARRAY[index__]), &(ARRAY[LY_ARRAY_COUNT(ARRAY) - 1]), sizeof *(ARRAY)); \ } \ remove__ = 1; \ + break; \ } \ } \ if (remove__) { \ diff --git a/tests/utests/data/test_tree_data.c b/tests/utests/data/test_tree_data.c index f451571fa..f022e3cff 100644 --- a/tests/utests/data/test_tree_data.c +++ b/tests/utests/data/test_tree_data.c @@ -598,7 +598,7 @@ test_data_leafref_nodes(void **state) { struct lyd_node *tree, *iter; struct lyd_node_term *target_node, *leafref_node; - struct lyd_leafref_links_rec *rec; + const struct lyd_leafref_links_rec *rec; const char *schema, *data, *value; ly_ctx_set_options(UTEST_LYCTX, LY_CTX_LEAFREF_LINKING); @@ -649,36 +649,36 @@ test_data_leafref_nodes(void **state) } /* verify state after leafref plugin validation */ - assert_int_equal(LY_SUCCESS, lyd_get_leafref_links(target_node, &rec)); + assert_int_equal(LY_SUCCESS, lyd_leafref_get_links(target_node, &rec)); assert_int_equal(1, LY_ARRAY_COUNT(rec->leafref_nodes)); - assert_int_equal(LY_SUCCESS, lyd_get_leafref_links(leafref_node, &rec)); + assert_int_equal(LY_SUCCESS, lyd_leafref_get_links(leafref_node, &rec)); assert_ptr_equal(rec->target_node, target_node); /* value modification of target */ assert_int_equal(LY_SUCCESS, lyd_change_term((struct lyd_node *)target_node, "ASD")); - assert_int_equal(LY_ENOTFOUND, lyd_get_leafref_links(target_node, &rec)); - assert_int_equal(LY_ENOTFOUND, lyd_get_leafref_links(leafref_node, &rec)); + assert_int_equal(LY_ENOTFOUND, lyd_leafref_get_links(target_node, &rec)); + assert_int_equal(LY_ENOTFOUND, lyd_leafref_get_links(leafref_node, &rec)); /* change back to original value */ assert_int_equal(LY_SUCCESS, lyd_change_term((struct lyd_node *)target_node, "asd")); - assert_int_equal(LY_ENOTFOUND, lyd_get_leafref_links(target_node, &rec)); - assert_int_equal(LY_ENOTFOUND, lyd_get_leafref_links(leafref_node, &rec)); + assert_int_equal(LY_ENOTFOUND, lyd_leafref_get_links(target_node, &rec)); + assert_int_equal(LY_ENOTFOUND, lyd_leafref_get_links(leafref_node, &rec)); /* linking the whole tree again */ - assert_int_equal(LY_SUCCESS, lyd_link_leafref_node_tree(tree)); - assert_int_equal(LY_SUCCESS, lyd_get_leafref_links(target_node, &rec)); + assert_int_equal(LY_SUCCESS, lyd_leafref_link_node_tree(tree)); + assert_int_equal(LY_SUCCESS, lyd_leafref_get_links(target_node, &rec)); assert_int_equal(1, LY_ARRAY_COUNT(rec->leafref_nodes)); - assert_int_equal(LY_SUCCESS, lyd_get_leafref_links(leafref_node, &rec)); + assert_int_equal(LY_SUCCESS, lyd_leafref_get_links(leafref_node, &rec)); assert_ptr_equal(rec->target_node, target_node); /* value modification of leafref */ assert_int_equal(LY_SUCCESS, lyd_change_term((struct lyd_node *)leafref_node, "qwe")); - assert_int_equal(LY_ENOTFOUND, lyd_get_leafref_links(target_node, &rec)); - assert_int_equal(LY_ENOTFOUND, lyd_get_leafref_links(leafref_node, &rec)); + assert_int_equal(LY_ENOTFOUND, lyd_leafref_get_links(target_node, &rec)); + assert_int_equal(LY_ENOTFOUND, lyd_leafref_get_links(leafref_node, &rec)); assert_int_equal(LY_SUCCESS, lyd_change_term((struct lyd_node *)leafref_node, "asd")); - assert_int_equal(LY_ENOTFOUND, lyd_get_leafref_links(target_node, &rec)); - assert_int_equal(LY_ENOTFOUND, lyd_get_leafref_links(leafref_node, &rec)); + assert_int_equal(LY_ENOTFOUND, lyd_leafref_get_links(target_node, &rec)); + assert_int_equal(LY_ENOTFOUND, lyd_leafref_get_links(leafref_node, &rec)); /* linking the whole tree again */ - assert_int_equal(LY_SUCCESS, lyd_link_leafref_node_tree(tree)); - assert_int_equal(LY_SUCCESS, lyd_get_leafref_links(target_node, &rec)); + assert_int_equal(LY_SUCCESS, lyd_leafref_link_node_tree(tree)); + assert_int_equal(LY_SUCCESS, lyd_leafref_get_links(target_node, &rec)); assert_int_equal(1, LY_ARRAY_COUNT(rec->leafref_nodes)); - assert_int_equal(LY_SUCCESS, lyd_get_leafref_links(leafref_node, &rec)); + assert_int_equal(LY_SUCCESS, lyd_leafref_get_links(leafref_node, &rec)); assert_ptr_equal(rec->target_node, target_node); /* freeing whole tree */ lyd_free_all(tree);