Skip to content

Commit af6c76f

Browse files
michalvaskobradh352
andcommitted
tree schema UPDATE function for getting all leafref targets
Co-authored-by: Brad House <[email protected]>
1 parent 775d24c commit af6c76f

File tree

2 files changed

+80
-10
lines changed

2 files changed

+80
-10
lines changed

src/tree_schema.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1908,13 +1908,25 @@ LIBYANG_API_DECL struct lysc_must *lysc_node_musts(const struct lysc_node *node)
19081908
LIBYANG_API_DECL struct lysc_when **lysc_node_when(const struct lysc_node *node);
19091909

19101910
/**
1911-
* @brief Get the target node of a leafref node.
1911+
* @brief Get the target node of a leafref node. Function ::lysc_node_lref_targets() should be used instead
1912+
* to get all the leafref targets even for a union node.
19121913
*
19131914
* @param[in] node Leafref node.
19141915
* @return Leafref target, NULL on any error.
19151916
*/
19161917
LIBYANG_API_DECL const struct lysc_node *lysc_node_lref_target(const struct lysc_node *node);
19171918

1919+
/**
1920+
* @brief Get the target node(s) of a leafref node or union node with leafrefs.
1921+
*
1922+
* @param[in] node Term node to use.
1923+
* @param[out] set Set with all the leafref targets, may be empty if the node is a different type or the targets
1924+
* are not found.
1925+
* @return LY_SUCCESS on success.
1926+
* @return LY_ERR value on error.
1927+
*/
1928+
LIBYANG_API_DECL LY_ERR lysc_node_lref_targets(const struct lysc_node *node, struct ly_set **set);
1929+
19181930
/**
19191931
* @brief Callback to be called for every schema node in a DFS traversal.
19201932
*

src/tree_schema_common.c

Lines changed: 67 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1804,21 +1804,24 @@ lysc_node_when(const struct lysc_node *node)
18041804
}
18051805
}
18061806

1807-
LIBYANG_API_DEF const struct lysc_node *
1808-
lysc_node_lref_target(const struct lysc_node *node)
1807+
/**
1808+
* @brief Get the target node of a leafref.
1809+
*
1810+
* @param[in] node Context node for the leafref.
1811+
* @param[in] type Leafref type to resolve.
1812+
* @return Target schema node;
1813+
* @return NULL if the tearget is not found.
1814+
*/
1815+
static const struct lysc_node *
1816+
lysc_type_lref_target(const struct lysc_node *node, const struct lysc_type *type)
18091817
{
18101818
struct lysc_type_leafref *lref;
18111819
struct ly_path *p;
18121820
const struct lysc_node *target;
18131821

1814-
if (!node || !(node->nodetype & LYD_NODE_TERM)) {
1815-
return NULL;
1816-
}
1822+
assert(type->basetype == LY_TYPE_LEAFREF);
18171823

1818-
lref = (struct lysc_type_leafref *)((struct lysc_node_leaf *)node)->type;
1819-
if (lref->basetype != LY_TYPE_LEAFREF) {
1820-
return NULL;
1821-
}
1824+
lref = (struct lysc_type_leafref *)type;
18221825

18231826
/* compile the path */
18241827
if (ly_path_compile_leafref(node->module->ctx, node, NULL, lref->path,
@@ -1834,6 +1837,61 @@ lysc_node_lref_target(const struct lysc_node *node)
18341837
return target;
18351838
}
18361839

1840+
LIBYANG_API_DEF const struct lysc_node *
1841+
lysc_node_lref_target(const struct lysc_node *node)
1842+
{
1843+
if (!node || !(node->nodetype & LYD_NODE_TERM) || (((struct lysc_node_leaf *)node)->type->basetype != LY_TYPE_LEAFREF)) {
1844+
return NULL;
1845+
}
1846+
1847+
return lysc_type_lref_target(node, ((struct lysc_node_leaf *)node)->type);
1848+
}
1849+
1850+
LIBYANG_API_DEF LY_ERR
1851+
lysc_node_lref_targets(const struct lysc_node *node, struct ly_set **set)
1852+
{
1853+
LY_ERR rc = LY_SUCCESS;
1854+
struct lysc_type *type;
1855+
struct lysc_type_union *type_un;
1856+
const struct lysc_node *target;
1857+
LY_ARRAY_COUNT_TYPE u;
1858+
1859+
LY_CHECK_ARG_RET(NULL, node, (node->nodetype & LYD_NODE_TERM), LY_EINVAL);
1860+
1861+
/* allocate return set */
1862+
LY_CHECK_RET(ly_set_new(set));
1863+
1864+
type = ((struct lysc_node_leaf *)node)->type;
1865+
if (type->basetype == LY_TYPE_UNION) {
1866+
/* union with possible leafrefs */
1867+
type_un = (struct lysc_type_union *)type;
1868+
1869+
LY_ARRAY_FOR(type_un->types, u) {
1870+
if (type_un->types[u]->basetype != LY_TYPE_LEAFREF) {
1871+
continue;
1872+
}
1873+
1874+
target = lysc_type_lref_target(node, type_un->types[u]);
1875+
if (target) {
1876+
LY_CHECK_GOTO(rc = ly_set_add(*set, target, 1, NULL), cleanup);
1877+
}
1878+
}
1879+
} else if (type->basetype == LY_TYPE_LEAFREF) {
1880+
/* leafref */
1881+
target = lysc_type_lref_target(node, type);
1882+
if (target) {
1883+
LY_CHECK_GOTO(rc = ly_set_add(*set, target, 1, NULL), cleanup);
1884+
}
1885+
}
1886+
1887+
cleanup:
1888+
if (rc) {
1889+
ly_set_free(*set, NULL);
1890+
*set = NULL;
1891+
}
1892+
return rc;
1893+
}
1894+
18371895
enum ly_stmt
18381896
lysp_match_kw(struct ly_in *in, uint64_t *indent)
18391897
{

0 commit comments

Comments
 (0)