@@ -1892,6 +1892,109 @@ lysc_node_lref_targets(const struct lysc_node *node, struct ly_set **set)
18921892 return rc ;
18931893}
18941894
1895+ struct lysc_node_lref_backlings_arg {
1896+ const struct lysc_node * node ;
1897+ ly_bool match_ancestors ;
1898+ struct ly_set * set ;
1899+ };
1900+
1901+ static LY_ERR
1902+ lysc_node_lref_backlinks_clb (struct lysc_node * node , void * data , ly_bool * dfs_continue )
1903+ {
1904+ LY_ERR rc = LY_SUCCESS ;
1905+ struct lysc_node_lref_backlings_arg * arg = data ;
1906+ struct ly_set * set = NULL ;
1907+ const struct lysc_node * par ;
1908+ uint32_t i ;
1909+
1910+ (void )dfs_continue ;
1911+
1912+ if (!(node -> nodetype & LYD_NODE_TERM )) {
1913+ /* skip */
1914+ goto cleanup ;
1915+ }
1916+
1917+ /* get all the leafref targets */
1918+ LY_CHECK_GOTO (rc = lysc_node_lref_targets (node , & set ), cleanup );
1919+
1920+ /* ignore node if has no leafref targets */
1921+ if (!set -> count ) {
1922+ goto cleanup ;
1923+ }
1924+
1925+ /* if just collecting leafrefs, we are done */
1926+ if (!arg -> node ) {
1927+ rc = ly_set_add (arg -> set , node , 1 , NULL );
1928+ goto cleanup ;
1929+ }
1930+
1931+ /* check that the node (or the ancestor of) is the target of this leafref */
1932+ for (i = 0 ; i < set -> count ; ++ i ) {
1933+ for (par = set -> snodes [i ]; par ; par = par -> parent ) {
1934+ if (par == arg -> node ) {
1935+ /* match */
1936+ break ;
1937+ }
1938+
1939+ if (!arg -> match_ancestors ) {
1940+ /* not a match */
1941+ par = NULL ;
1942+ break ;
1943+ }
1944+ }
1945+
1946+ if (par ) {
1947+ /* add into the set, matches */
1948+ LY_CHECK_GOTO (rc = ly_set_add (arg -> set , node , 1 , NULL ), cleanup );
1949+ break ;
1950+ }
1951+ }
1952+
1953+ cleanup :
1954+ ly_set_free (set , NULL );
1955+ return rc ;
1956+ }
1957+
1958+ LIBYANG_API_DEF LY_ERR
1959+ lysc_node_lref_backlinks (const struct ly_ctx * ctx , const struct lysc_node * node , ly_bool match_ancestors ,
1960+ struct ly_set * * set )
1961+ {
1962+ LY_ERR rc = LY_SUCCESS ;
1963+ struct lysc_node_lref_backlings_arg arg = {0 };
1964+ uint32_t idx = 0 ;
1965+ const struct lys_module * mod ;
1966+
1967+ LY_CHECK_ARG_RET (NULL , ctx || node , set , LY_EINVAL );
1968+
1969+ if (!ctx ) {
1970+ ctx = node -> module -> ctx ;
1971+ }
1972+
1973+ /* allocate return set */
1974+ LY_CHECK_RET (ly_set_new (set ));
1975+
1976+ /* prepare the arg */
1977+ arg .node = node ;
1978+ arg .match_ancestors = match_ancestors ;
1979+ arg .set = * set ;
1980+
1981+ /* iterate across all loaded modules */
1982+ while ((mod = ly_ctx_get_module_iter (ctx , & idx ))) {
1983+ if (!mod -> compiled ) {
1984+ continue ;
1985+ }
1986+
1987+ LY_CHECK_GOTO (rc = lysc_module_dfs_full (mod , lysc_node_lref_backlinks_clb , & arg ), cleanup );
1988+ }
1989+
1990+ cleanup :
1991+ if (rc ) {
1992+ ly_set_free (* set , NULL );
1993+ * set = NULL ;
1994+ }
1995+ return rc ;
1996+ }
1997+
18951998enum ly_stmt
18961999lysp_match_kw (struct ly_in * in , uint64_t * indent )
18972000{
0 commit comments