@@ -1892,6 +1892,109 @@ lysc_node_lref_targets(const struct lysc_node *node, struct ly_set **set)
1892
1892
return rc ;
1893
1893
}
1894
1894
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
+
1895
1998
enum ly_stmt
1896
1999
lysp_match_kw (struct ly_in * in , uint64_t * indent )
1897
2000
{
0 commit comments